> Что такое битовые сдвиги и где они применяются (Android)
Уровень: junior · Роль: mobile · Категория: Технические вопросы
Компании: Иннотех
Стек: Android
> Пример ответа
Короткий ответ
Битовые сдвиги - это операции, которые перемещают биты числа влево или вправо. В Java есть три оператора: << (сдвиг влево), >> (сдвиг вправо с сохранением знака) и >>> (логический сдвиг вправо без знака). Сдвиг влево эквивалентен умножению на степень двойки, сдвиг вправо - целочисленному делению. Применяются для быстрых вычислений, работы с флагами, битовыми масками, в криптографии, сжатии и низкоуровневых операциях.
Подробное объяснение
Битовый сдвиг - это операция над целочисленными типами (int, long, byte, short, char), которая перемещает каждый бит числа на заданное количество позиций. Освободившиеся позиции заполняются нулями (для << и >>>) или значением знакового бита (для >>).
Основные операторы в Java:
a << n- сдвиг влево наnпозиций. Каждый бит перемещается в старший разряд, младшие биты заполняются нулями. Эквивалентноa * 2^n(при отсутствии переполнения).a >> n- арифметический сдвиг вправо. Старшие биты заполняются значением знакового бита (0 для положительных, 1 для отрицательных). Эквивалентноa / 2^nс округлением вниз.a >>> n- логический сдвиг вправо. Старшие биты всегда заполняются нулями, независимо от знака.
Важные особенности:
- Для
intсдвиг выполняется по модулю 32 (n & 0x1F), дляlong- по модулю 64. - Сдвиг на отрицательное число или число больше разрядности не приводит к ошибке - берётся младшие 5 (или 6) бит.
- Приоритет операторов сдвига ниже, чем у арифметических, но выше, чем у сравнения.
На практике
В Android-разработке битовые сдвиги встречаются в нескольких типичных местах:
- Работа с флагами и битовыми масками - например, в
Viewдля хранения системных флагов (VISIBLE,GONE), вPackageManagerдля флагов установки, вIntentдля флагов запуска. - Оптимизация вычислений - умножение и деление на степень двойки через сдвиг быстрее, чем через арифметические операции (хотя современные компиляторы делают это автоматически).
- Работа с цветом - в Android цвет хранится как
int(ARGB), и для извлечения компонентов используются сдвиги:(color >> 16) & 0xFFдля красного канала. - Сериализация и парсинг бинарных данных - например, при работе с
ByteBuffer, протоколами или файловыми форматами. - Хеширование - в
HashMapиспользуется(h = key.hashCode()) ^ (h >>> 16)для улучшения распределения. - Анимации и графические трансформации - в
Matrix,Rectи других геометрических классах иногда используются сдвиги для быстрых вычислений.
Пример кода
JAVA// Извлечение компонентов цвета ARGBint color = 0xAABBCCDD;int alpha = (color >>> 24) & 0xFF;int red = (color >>> 16) & 0xFF;int green = (color >>> 8) & 0xFF;int blue = color & 0xFF;// Упаковка обратноint packed = (alpha << 24) | (red << 16) | (green << 8) | blue;// Умножение и деление на степень двойкиint value = 10;int multiplied = value << 3; // 10 * 8 = 80int divided = value >> 2; // 10 / 4 = 2 (целочисленное)// Проверка установленного битаint flags = 0b1010;boolean isSecondBitSet = (flags & (1 << 1)) != 0; // true// Логический сдвиг для беззнаковых значенийint negative = -1;int unsigned = negative >>> 1; // 2147483647
Как отвечать на собеседовании
Начни с определения и трёх операторов. Скажи, что сдвиг влево - это умножение на степень двойки, арифметический сдвиг вправо - деление с округлением вниз. Упомяни разницу между >> и >>> - это ключевой момент для junior. Приведи один-два примера из Android: извлечение цвета или работа с флагами. Если спросят про производительность - скажи, что сдвиг быстрее умножения, но в Java компилятор сам оптимизирует умножение на степень двойки, поэтому явный сдвиг нужен скорее для читаемости или при работе с битовыми масками.
Что проверяет интервьюер
Интервьюер проверяет:
- Понимание двоичного представления чисел и побитовых операций в целом.
- Знание разницы между арифметическим и логическим сдвигом вправо.
- Умение применять сдвиги на практике - например, извлечение байтов из
int. - Понимание особенностей Java: сдвиг по модулю разрядности, поведение для отрицательных чисел.
- Способность объяснить, зачем это нужно в реальной разработке, а не только в теории.
Типичные ошибки
- Путать
>>и>>>- не помнить, что>>сохраняет знак, а>>>всегда заполняет нулями. - Забывать про приоритет операторов:
a & b << cинтерпретируется какa & (b << c), а не(a & b) << c. - Использовать сдвиг для
byteилиshortбез приведения - результат всегдаint, и это может привести к неожиданному поведению. - Сдвигать на количество бит, превышающее разрядность типа, не учитывая модуль 32/64.
- Думать, что сдвиг вправо для отрицательных чисел - это деление с округлением к нулю. На самом деле это округление вниз (к отрицательной бесконечности).
- Использовать сдвиг для оптимизации там, где это не нужно - современный JIT и так заменяет умножение на степень двойки сдвигом.
> Похожие задачи по mobile
Как работает get в Map
Знаете ли вы полную аббревиатуру state machine
Как проверить, что все значения в мапе равны нулю
Какая структура данных подходит для хранения количества букв в строках при проверке анаграмм
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью