> Как реализовать добавление цифр к результату с помощью append и слайса байт в Go (Go)
Уровень: middle · Роль: backend · Категория: Технические вопросы
Компании: МайлРу
Стек: Go
> Пример ответа
Короткий ответ
Чтобы добавить цифры к результату в Go, используют strconv.AppendInt, strconv.AppendUint или strconv.AppendFloat - они принимают слайс байт как первый аргумент и возвращают расширенный слайс. Альтернативно можно вручную конвертировать цифру в байт через byte('0' + digit) и делать append. Основной принцип: append мутирует слайс при достаточной ёмкости или выделяет новый, поэтому результат всегда присваивают обратно.
Подробное объяснение
append в Go работает с любым типом элемента, включая byte. Для цифр есть два подхода:
-
Через
strconv- стандартный способ для чисел любой разрядности. Функции видаAppendInt(dst []byte, i int64, base int) []byteдобавляют строковое представление числа к существующему слайсу. Это эффективно, так как не создаёт промежуточную строку. -
Вручную - если нужно добавить одну цифру от 0 до 9, можно использовать арифметику:
digit := n % 10, затемresult = append(result, byte('0'+digit)). Это работает, потому что коды символов цифр идут подряд.
Важно понимать поведение append: если ёмкость слайса достаточна, он перезапишет элементы за текущей длиной и вернёт тот же слайс с увеличенной длиной. Если нет - выделит новый массив. Поэтому всегда нужно использовать возвращаемое значение: result = append(result, b).
При добавлении нескольких цифр числа (например, при ручной конвертации int в строку) порядок будет обратным - сначала получаем младший разряд, поэтому либо идём с конца числа, либо разворачиваем результат в конце.
На практике
Типичный сценарий - сборка строки или буфера из чисел без лишних аллокаций. Например, при формировании HTTP-ответа или сериализации. Вместо fmt.Sprintf и последующей конкатенации используют append с strconv, чтобы избежать создания промежуточных строк.
Для однозначных чисел ручной способ через byte('0'+digit) быстрее, чем вызов strconv, но для многозначных лучше использовать strconv.AppendInt - он уже оптимизирован.
Если нужно добавить цифру в начало результата, удобнее сначала собрать в обратном порядке, а затем развернуть слайс через slices.Reverse (Go 1.21+) или вручную.
Пример кода
GOpackage mainimport ("fmt""strconv")func main() {// Способ 1: через strconvresult := make([]byte, 0, 16)result = strconv.AppendInt(result, 12345, 10)result = append(result, ' ') // добавляем пробелresult = strconv.AppendInt(result, -678, 10)fmt.Println(string(result)) // "12345 -678"// Способ 2: ручное добавление одной цифрыvar digits []byten := 7digits = append(digits, byte('0'+n))fmt.Println(string(digits)) // "7"// Способ 3: ручная конвертация многозначного числаnum := 9876var buf []bytefor num > 0 {digit := num % 10buf = append(buf, byte('0'+digit))num /= 10}// разворачиваем, так как цифры собраны в обратном порядкеfor i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {buf[i], buf[j] = buf[j], buf[i]}fmt.Println(string(buf)) // "9876"}
Как отвечать на собеседовании
Начни с упоминания strconv.AppendInt как основного инструмента, затем покажи ручной способ для одиночных цифр. Обязательно подчеркни, почему результат append нужно присваивать обратно - это частый вопрос на понимание устройства слайсов. Приведи пример с буфером и объясни, почему это эффективнее конкатенации строк. Если спросят про производительность, скажи, что append с предварительным выделением ёмкости (make([]byte, 0, n)) избегает лишних аллокаций.
Что проверяет интервьюер
Интервьюер оценивает:
- понимание работы
appendи слайсов (ёмкость, длина, возможное перераспределение); - знание стандартной библиотеки (
strconv); - умение работать с байтами и кодами символов;
- способность написать код без лишних аллокаций и промежуточных строк.
Типичные ошибки
- Игнорирование возвращаемого значения
append- если ёмкость превышена, исходный слайс не изменится, и данные потеряются. - Попытка добавить цифру как
append(result, digit)без преобразования вbyte- получится не символ, а управляющий код. - Забывают про обратный порядок при ручной конвертации числа в строку.
- Использование
fmt.Sprintfвнутри цикла для каждой цифры - это создаёт лишние аллокации и замедляет код.
> Похожие задачи по backend
Используете ли алертинг через Grafana
Используете ли трейсинг, например Jaeger
Какой план действий при перегрузке CPU и срабатывании алерта
В чем разница наследования в Go и классического наследования
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью