Forwarded from Golang
🔐 Boulder — реализация ACME-совместимого центра сертификации, автоматически проверяющего владение доменом и выпускающего TLS-сертификаты. Именно на нём работает Let’s Encrypt, бесплатно обеспечивая шифрование для миллионов сайтов.
Проект разделён на компоненты: Web Frontend, Registration Authority, Certificate Authority и другие, что позволяет изолировать критичные части системы. Внутри — строгая логика на основе объектов ACME: аккаунтов, авторизаций и сертификатов. Для связи между модулями используется gRPC, а для разработки — Docker-окружение с полным набором зависимостей.
🤖 GitHub
@golang_google
Проект разделён на компоненты: Web Frontend, Registration Authority, Certificate Authority и другие, что позволяет изолировать критичные части системы. Внутри — строгая логика на основе объектов ACME: аккаунтов, авторизаций и сертификатов. Для связи между модулями используется gRPC, а для разработки — Docker-окружение с полным набором зависимостей.
🤖 GitHub
@golang_google
🧠 Задача для Go-разработчиков: "Подозрительно сбалансированное число"
Условие
Найди наименьшее положительное целое число
1. Цифры
2.
3.
Найди такое число, напиши код, который это делает эффективно, и объясни, почему перебор — не самый лучший способ.
Пример:
---
📌 Реализуй функцию:
---
Подсказка:
Задача решается быстрее, если строить палиндромы по шаблону, а не перебирать все числа подряд.
---
🔍 Решение:
```go
package main
import (
"fmt"
"strconv"
)
func isBalanced(digits []int) bool {
n := len(digits)
for i := 1; i < n; i++ {
left := digits[:i]
right := digits[i:]
sumL, sumR := 0, 0
for _, d := range left {
sumL += d
}
for _, d := range right {
sumR += d
}
if sumL == sumR {
return true
}
}
return false
}
func FindBalancedPalindrome() int {
for i := 11; ; i++ {
if i%10 == 0 {
continue
}
s := strconv.Itoa(i)
rev := reverse(s)
if s != rev {
continue
}
digits := make([]int, len(s))
for idx, ch := range s {
digits[idx] = int(ch - '0')
}
if isBalanced(digits) {
return i
}
}
}
func reverse(s string) string {
r := []rune(s)
for i := 0; i < len(r)/2; i++ {
r[i], r[len(r)-1-i] = r[len(r)-1-i], r[i]
}
return string(r)
}
func main() {
fmt.Println("Ответ:", FindBalancedPalindrome())
}
```
✅ Объяснение:
1. Мы перебираем **только палиндромы**, игнорируя шум.
2. Для каждого палиндрома проверяем, можно ли разделить цифры на две группы с равной суммой.
3. Проверка выполняется за `O(n)` на каждое число, где `n` — длина числа.
Такой подход эффективнее полного перебора от 1 до бесконечности.
🔥 Эта задача проверяет:
• знание работы с цифрами и строками
• умение писать генераторы палиндромов
• понимание оптимизации перебора
• грамотное разбиение массива на подмассивы
• работу со строками и рунами в Go
Условие
Найди наименьшее положительное целое число
N
, для которого выполняются все три условия:1. Цифры
N
можно разделить на две группы, сумма которых равна (например: 3213
→ `3+2 = 1+3`).2.
N
является палиндромом (читается одинаково слева направо и справа налево).3.
N
не делится на 10 (исключаем очевидные трюки вроде "1001").Найди такое число, напиши код, который это делает эффективно, и объясни, почему перебор — не самый лучший способ.
Пример:
3213 -> цифры: [3,2,1,3]
Разделение: [3,2] и [1,3] → сумма 5 и 4 → не равны → не подходит
1331 -> [1,3,3,1] → [1,3]=4, [3,1]=4 → ✅ подходит (и палиндром, и сбалансирован)
---
📌 Реализуй функцию:
func FindBalancedPalindrome() int
---
Подсказка:
Задача решается быстрее, если строить палиндромы по шаблону, а не перебирать все числа подряд.
---
🔍 Решение:
```go
package main
import (
"fmt"
"strconv"
)
func isBalanced(digits []int) bool {
n := len(digits)
for i := 1; i < n; i++ {
left := digits[:i]
right := digits[i:]
sumL, sumR := 0, 0
for _, d := range left {
sumL += d
}
for _, d := range right {
sumR += d
}
if sumL == sumR {
return true
}
}
return false
}
func FindBalancedPalindrome() int {
for i := 11; ; i++ {
if i%10 == 0 {
continue
}
s := strconv.Itoa(i)
rev := reverse(s)
if s != rev {
continue
}
digits := make([]int, len(s))
for idx, ch := range s {
digits[idx] = int(ch - '0')
}
if isBalanced(digits) {
return i
}
}
}
func reverse(s string) string {
r := []rune(s)
for i := 0; i < len(r)/2; i++ {
r[i], r[len(r)-1-i] = r[len(r)-1-i], r[i]
}
return string(r)
}
func main() {
fmt.Println("Ответ:", FindBalancedPalindrome())
}
✅ Объяснение:
1. Мы перебираем **только палиндромы**, игнорируя шум.
2. Для каждого палиндрома проверяем, можно ли разделить цифры на две группы с равной суммой.
3. Проверка выполняется за `O(n)` на каждое число, где `n` — длина числа.
Такой подход эффективнее полного перебора от 1 до бесконечности.
🔥 Эта задача проверяет:
• знание работы с цифрами и строками
• умение писать генераторы палиндромов
• понимание оптимизации перебора
• грамотное разбиение массива на подмассивы
• работу со строками и рунами в Go
❓ Когда не получится применить бинарный поиск
Anonymous Quiz
10%
Если элементы массива — строки, а не числа
10%
Если в массиве есть дубликаты
73%
Если данные не отсортированы
7%
Узнать ответ
🐹 Задача для Go 1.21+: «Контекст отменён, но горутина продолжает работу»
📌 Актуально для: Go 1.21 и новее (введён `context.WithCancelCause`)
🎯 Цель: Понять, почему горутина не завершилась по отменённому контексту
📍 Ситуация:
Ты используешь контекст для управления жизненным циклом горутины. В Go 1.21 ты решил использовать
🔍 Ты ожидаешь, что горутина завершится и выведет:
Но вместо этого — программа завершилась без вывода. Почему?
🧩 Вопросы:
1. Почему
2. Что изменилось в
3. Как безопасно читать причину отмены?
4. Как изменить
5. Почему важно не блокироваться на `ctx.Done()`, если возможна гонка?
🛠 Решение:
🔸 В Go 1.21 есть `context.WithCancelCause`, который позволяет задавать причину отмены.
Но `context.Cause(ctx)` вернёт `nil`, **если ты используешь `context.WithCancel`**, либо, если `ctx.Done()` не был срабатывающим.
🔸 В этом коде `worker(ctx)` запускается и сразу блокируется на:
<-ctx.Done()
Но если отмена происходит **до** того, как `worker` успел начать слушать `ctx.Done()`, и ты используешь старую `WithCancel`, `context.Cause` вернёт `nil`.
🔸 **Правильный способ:**
Убедись, что `context.WithCancelCause` действительно используется и `ctx.Done()` слушается вовремя.
Для Go 1.21+ пример рабочий:
🔸 Альтернатива для старых версий Go (<1.21):
ctx, cancel := context.WithCancel(context.Background())
...
fmt.Println("Worker stopped:", ctx.Err()) // вместо Cause
📌 Вывод:
Начиная с Go 1.21, `context.WithCancelCause` даёт более точный контроль за причинами отмены. Но горутины всё равно должны явно проверять `ctx.Done()` через `select`, иначе отмена может пройти незаметно.
📌 Актуально для: Go 1.21 и новее (введён `context.WithCancelCause`)
🎯 Цель: Понять, почему горутина не завершилась по отменённому контексту
📍 Ситуация:
Ты используешь контекст для управления жизненным циклом горутины. В Go 1.21 ты решил использовать
context.WithCancelCause
:
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithCancelCause(context.Background())
go worker(ctx)
time.Sleep(1 * time.Second)
cancel(fmt.Errorf("manual stop"))
time.Sleep(2 * time.Second)
}
func worker(ctx context.Context) {
<-ctx.Done()
fmt.Println("Worker stopped:", context.Cause(ctx))
}
🔍 Ты ожидаешь, что горутина завершится и выведет:
Worker stopped: manual stop
Но вместо этого — программа завершилась без вывода. Почему?
🧩 Вопросы:
1. Почему
worker
не печатает "Worker stopped: ..."
? 2. Что изменилось в
context.WithCancelCause
по сравнению с WithCancel
? 3. Как безопасно читать причину отмены?
4. Как изменить
worker
, чтобы он корректно завершался? 5. Почему важно не блокироваться на `ctx.Done()`, если возможна гонка?
🛠 Решение:
Но `context.Cause(ctx)` вернёт `nil`, **если ты используешь `context.WithCancel`**, либо, если `ctx.Done()` не был срабатывающим.
🔸 В этом коде `worker(ctx)` запускается и сразу блокируется на:
🔸 **Правильный способ:**
Убедись, что `context.WithCancelCause` действительно используется и `ctx.Done()` слушается вовремя.
Для Go 1.21+ пример рабочий:
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Worker stopped:", context.Cause(ctx))
return
case <-time.After(100 * time.Millisecond):
fmt.Println("Working...")
}
}
}
🔸 Альтернатива для старых версий Go (<1.21):
...
fmt.Println("Worker stopped:", ctx.Err()) // вместо Cause
📌 Вывод:
This media is not supported in your browser
VIEW IN TELEGRAM
Раньше: многоэтапные собеседования и тестовые
Сейчас: возможность получить оффер за один день!
Сбер зовёт Go-разработчиков на One Day Offer — он пройдёт 21 июня в онлайн-формате. Команда ищет будущих коллег в рекламную платформу SberAds сразу в несколько продуктов:
— Медийная реклама
— Performance Ads
— Инструменты разработки
— RTS
Регистрируйтесь на One Day Offer и будьте готовы к карьерным изменениям и работой над действительно масштабными задачами!
Сейчас: возможность получить оффер за один день!
Сбер зовёт Go-разработчиков на One Day Offer — он пройдёт 21 июня в онлайн-формате. Команда ищет будущих коллег в рекламную платформу SberAds сразу в несколько продуктов:
— Медийная реклама
— Performance Ads
— Инструменты разработки
— RTS
Регистрируйтесь на One Day Offer и будьте готовы к карьерным изменениям и работой над действительно масштабными задачами!
🐿️ Задача на логику для собеседования back-end разработчика на GO
— Мы знаем, что в десятичной системе самое большое число из одной цифры - это 9, а из двух - 99. В бинарной системе самое большое число из двух цифр это 11 (3) самое большое число из трех цифр это 111 (7) и самое большое число из 4 цифр это 1111 (15).
Вопрос: каково самое большое число из 8 цифр?
— Подсказка:
1️⃣101 - 1 = 9, a 102 - 1 = 99 (Решение через знание степеней 2)
2️⃣11110 это 15 * 2 = 30, а 111100 это 15 * 2 * 2 = 60 (Решение через битовый сдвиг)
Ответ:
255
@golang_interview
— Мы знаем, что в десятичной системе самое большое число из одной цифры - это 9, а из двух - 99. В бинарной системе самое большое число из двух цифр это 11 (3) самое большое число из трех цифр это 111 (7) и самое большое число из 4 цифр это 1111 (15).
Вопрос: каково самое большое число из 8 цифр?
— Подсказка:
1️⃣
2️⃣
Ответ:
@golang_interview
нехватка времени или строгие дедлайны? Тогда советуем обратить внимание на бесплатные курсы Яндекс Лицея по Python, Go и C++ для начинающих.
Заниматься на них можно когда и где угодно, ведь уроки доступны онлайн и в них нет дедлайнов! Вас ждут:
✅ Качество: занятия разработаны практикующими экспертами Яндекса.
✅ Свобода: пользуйтесь автоматической проверкой решений и задавайте вопросы через поддержку.
✅ Перспективы: после завершения вы получите уверенную базу для дальнейшего роста, а также сертификат, который пригодится при поступлении в Яндекс Лицей.
Не откладывайте на потом — выберите курс и зарегистрируйтесь на сайте!
Заниматься на них можно когда и где угодно, ведь уроки доступны онлайн и в них нет дедлайнов! Вас ждут:
✅ Качество: занятия разработаны практикующими экспертами Яндекса.
✅ Свобода: пользуйтесь автоматической проверкой решений и задавайте вопросы через поддержку.
✅ Перспективы: после завершения вы получите уверенную базу для дальнейшего роста, а также сертификат, который пригодится при поступлении в Яндекс Лицей.
Не откладывайте на потом — выберите курс и зарегистрируйтесь на сайте!
❓ Что произойдёт, если два маршрута в Go-пакете net/http пересекаются и соответствуют одному запросу
Anonymous Quiz
39%
Будет выбран первый зарегистрированный маршрут
23%
Выберется последний зарегистрированный маршрут
21%
Произойдёт ошибка маршрутизации
18%
Будут выполнены оба обработчика маршрутов
🐹 Go-задача (Go 1.22+): почему вывод вас удивит?
❓ Что напечатает программа?
• a)
• b)
• c)
• d)
package main
import "fmt"
func main() {
words := []string{"go", "rust", "zig"}
ptrs := []*string{}
for i, v := range words {
if i == 1 {
words = append(words, "odin") // добавляем элемент во время range
}
ptrs = append(ptrs, &v) // сохраняем адрес переменной v
}
for _, p := range ptrs {
fmt.Println(*p)
}
}
❓ Что напечатает программа?
• a)
go rust zig
• b)
go rust zig odin
• c)
zig zig zig zig
• d)
go rust zig odin
, затем паника