Как распределять ширины детей, если все относительные значения отрицательные
Что проверяют
Обычно это продолжение задачи на собственный layout: у детей есть фиксированные ширины и относительные веса, остаток родителя делится по весам. Вопрос про отрицательные веса проверяет, думаете ли вы о контракте и граничных случаях до того, как делить на сумму. Следом спрашивают про смешанный случай, где веса разного знака.
Как отвечать
Сначала уточните требование: что значит отрицательный вес в этом API. Разумных вариантов два, назовите оба:
- ошибка входных данных: так делает Compose,
Modifier.weight()бросаетIllegalArgumentExceptionна весе меньше или равном нулю. Для публичного API это самый честный вариант; - приравнять к нулю: отрицательный вес считается нулевым, ребёнок получает свою минимальную ширину или 0. Если так обнулились все, делить нечего, остаток просто остаётся пустым.
Сам алгоритм:
- первый проход: измерить детей с фиксированной шириной,
remainingравен ширине родителя минус их сумма, обрезанный снизу нулём; - сумма весов: складывать только положительные веса. Если
totalWeight <= 0, распределение пропускается, никакого деления; - раздача: каждому
floor(remaining * w / totalWeight), а пиксели, оставшиеся от округления, раздаются по одному детям с наибольшей дробной частью, чтобы сумма ширин точно совпала сremaining; - тесты: пустой список, все веса отрицательные, сумма ровно ноль, фиксированные дети шире родителя.
В классическом LinearLayout логика похожая: layout_weight делит оставшееся место, а android:weightSum задаёт знаменатель явно.
Где спотыкаются
Суммируют все веса вместе с отрицательными. Для весов 3 и -2 сумма равна 1, первый ребёнок получает втрое больше остатка и вылезает за родителя, а при 1 и -1 выходит деление на ноль.
Делят во Float и приводят к Int без учёта остатка, из-за чего справа остаётся полоска в пару пикселей.
Пишут код молча, не спросив про контракт. Интервьюер ждёт именно вопроса «что должно происходить в этом случае?», а не угаданного поведения.