Булева логика и фильтры: вопросы для собеседования (часть 4)

AND, OR, NOT, законы де Моргана, приоритет операторов — булева логика лежит в основе фильтрации данных в SQL и Python. На собеседовании дают сложное условие с вложенными AND/OR и просят определить, какие строки пройдут фильтр. Ошибки в логических выражениях — одна из самых частых причин неправильных результатов.

Качество данных и инвариантыВоронки и когортные рассужденияJOIN и кардинальностьПостановка задачиДоли и процентыSanity-check и оценкаСегментация и конфаундингТеория множеств и дедупликацияВзвешенные средние и смешение

Вопросы 1620 из 20

16Нужно оставить только внешних пользователей: исключить тех, у кого `is_internal = 1` `OR` `is_bot = 1`. Какой фильтр корректен?
A`NOT (is_internal = 1) OR NOT (is_bot = 1)`
B`is_internal = 0 OR is_bot = 0`
C`NOT (is_internal = 1 AND is_bot = 1)`
D`NOT (is_internal = 1 OR is_bot = 1)`
Ответ: Если «плохая группа» задана как `is_internal = 1 OR is_bot = 1`, то её исключение записывается как `NOT (is_internal = 1 OR is_bot = 1)`.

Чтобы исключить всех, кто удовлетворяет хотя бы одному из условий, сначала объединяют их через `OR`, а затем берут отрицание всей скобки. По `De Morgan` это эквивалентно `NOT (is_internal = 1) AND NOT (is_bot = 1)`, что часто читается ещё яснее. Вариант `NOT (A) OR NOT (B)` слишком мягкий и оставляет пользователей, у которых выполнено одно из «плохих» условий.

17В фильтре написали `country = 'RU' AND device = 'ios' OR device = 'android'`. Какой набор строк реально пройдёт фильтр при стандартном приоритете, где `AND` сильнее `OR`?
AТолько строки, где `country = 'RU' AND (device = 'ios' OR device = 'android')`.
BСтроки, где `(country = 'RU' AND device = 'ios') OR device = 'android'` (то есть `device = 'android'` из любой страны).
CТолько строки, где `country = 'RU' AND device = 'android'`.
DСтроки, где `country = 'RU' OR (device = 'ios' AND device = 'android')`.
Ответ: Без скобок `device = 'android'` становится отдельной веткой через `OR` и не зависит от `country = 'RU'`.

Сначала вычисляется часть `country = 'RU' AND device = 'ios'`. Затем результат объединяется с `device = 'android'` через `OR`, и поэтому все `android` попадают в выборку. Это типичная ошибка: хотели `country = 'RU' AND (device = 'ios' OR device = 'android')`, но забыли скобки.

18В таблице пользователей есть флаги `has_email_optin` и `has_push_optin` (0 или 1). Нужно выбрать пользователей, у которых включён ровно один канал (email или push, но не оба). Какое условие корректно?
A`(has_email_optin = 1 AND NOT (has_push_optin = 1)) OR (NOT (has_email_optin = 1) AND has_push_optin = 1)`
B`has_email_optin = 1 AND has_push_optin = 1`
C`has_email_optin = 1 OR has_push_optin = 1`
D`NOT (has_email_optin = 1 AND has_push_optin = 1)`
Ответ: «Ровно один» означает, что истинно одно условие, а второе ложно, поэтому объединяем два взаимно исключающих случая через `OR`.

Если включён только email, выполняется `has_email_optin = 1 AND NOT (has_push_optin = 1)`. Если включён только push, выполняется `NOT (has_email_optin = 1) AND has_push_optin = 1`. Объединяя эти два случая через `OR`, вы получаете ровно один истинный флаг. Условие `NOT (A AND B)` недостаточно, потому что оно пропускает также случай, когда не выполнено ни одно.

19Условие в фильтре написали как `(is_paying = 1 AND is_mobile = 1) OR (is_paying = 1 AND NOT (is_mobile = 1))`. Какому более простому условию оно эквивалентно?
A`is_mobile = 1`
B`is_paying = 1 AND is_mobile = 1`
C`is_paying = 1 OR is_mobile = 1`
D`is_paying = 1`
Ответ: Здесь `is_paying = 1` общий для обеих веток, а `is_mobile = 1 OR NOT (is_mobile = 1)` является `always true`.

Исходное выражение покрывает оба случая для `is_mobile`: когда флаг истинный и когда он ложный, но в обоих случаях требуется `is_paying = 1`. Поэтому объединение двух веток через `OR` не добавляет новых ограничений по `is_mobile`. Упрощение до `is_paying = 1` делает фильтр короче и снижает риск логических ошибок при дальнейших правках.

20Какое выражение эквивалентно условию `is_paying = 1 AND (country = 'RU' OR country = 'KZ')` без изменения смысла?
A`is_paying = 1 AND country = 'RU' OR country = 'KZ'`
B`(is_paying = 1 AND country = 'RU') OR (is_paying = 1 AND country = 'KZ')`
C`(is_paying = 1 OR country = 'RU') AND (is_paying = 1 OR country = 'KZ')`
D`is_paying = 1 OR (country = 'RU' AND country = 'KZ')`
Ответ: Условие `is_paying = 1 AND (country = 'RU' OR country = 'KZ')` можно переписать как `(is_paying = 1 AND country = 'RU') OR (is_paying = 1 AND country = 'KZ')`.

Это полезно, когда вы хотите явно увидеть два сценария, которые приводят к попаданию в сегмент. Важно не потерять скобки, иначе приоритет `AND`/`OR` изменит смысл. Такая форма часто помогает при дебаге, когда нужно понять, какая ветка `OR` сработала для конкретной строки.

1234

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать в Telegram

Другие темы: Логика

Качество данных и инвариантыВоронки и когортные рассужденияJOIN и кардинальностьПостановка задачиДоли и процентыSanity-check и оценкаСегментация и конфаундингТеория множеств и дедупликацияВзвешенные средние и смешение