Данетка для разработчика

В связи с прошедшим днем тестировщика и наступающим днем программиста (и тот и другой мои профессиональные праздники) предлагаю данетку.

Вы выдвигаете гипотезу, я подтверждаю ее правильность или неправильность. Конечные правильные ответы не показываются до конца игры. На блоге премодерация, так что не удивляйтесь, если не увидите ответ сразу.

—————————–

Идет тестирование банковской системы. Проверяются зарплатные долларовые счета. На счет положена сумма $800. Установлен лимит снятий $500.

1. Попытка снять $600 – отвергается системой

2. Попытка снять $400 – деньги сняты

3. Попытка снять $500 – деньги сняты

Вопрос: «Сколько денег осталось на счете?»

PS.  Дополнительный вопрос в стиле «Что, где, когда?»: почему лимит $500?

Комментариев: 49

  1. buzin написал:

    Сумма_на_счете_до_внесения_$800 - $100

  2. SALar написал:

    Сумма на счете до внесения была $0. Т.е. когда начались сами тесты (1. 2. 3.) на счете было $800.

  3. buzin написал:

    Тогда -$100 (овердрафт)

  4. gdevgencih написал:

    Может быть осталось 500$?
    После того как система отвергла операцию к счету были добавлены 600$, которые с него не снимали.

  5. chip написал:

    Вариант 0. Счет может уходить в минус. Остаток — $-100
    Вариант 1. 600 зачислено, остальное снято. Остаток — 500 долларов
    Вариант 2. Все зачисляется. Остаток — $2300
    Вариант 3. 1-я попытка игнорируется, вместо снятия деньги зачисляются. Остаток $1700

  6. chip написал:

    Вариант 5.
    Снимается в рублях. Остаток: $800 - 900р

  7. nh написал:

    Гипотеза 1. На счёте осталось $800: снятие фактически не работает.
    Гипотеза 2. На счёте осталось -$100: не работает проверка наличия достаточного количества средств.
    Гипотеза 3. На счёте осталось $0: проверки наличия средств нет, но остаток всегда принудительно “поддерживается” не меньше нуля.
    Гипотеза 4. На счёте осталось $800 + $400 + $500 = $ 1700: вместо операции снятия осуществляется операция пополнения.
    Гипотеза 5. На счёте осталось -$700: то же, что в гипотезе 2, но при этом при попытке снять $600 деньги были сняты, несмотря на внешний отказ.
    Гипотеза 6. На счёте осталось $2300: то же, что в гипотезе 4, но при этом при попытке “снять” $600 деньги были ошибочно начислены, несмотря на внешний отказ системы в проведении операции.
    Гипотеза 7. На счёте осталось $800 - $600 = $200: система путает операции “снятие” и “отказ в снятии”.
    Дальше возможны более тонкие разновидности подобных сценариев…

    Лимит $500, потому что система слишком бажная, и лучше не доверять ей крупных операций. $500 на покушать хватит, а крупные покупки лучше делать как-нибудь понадёжнее.

  8. nh написал:

    Поскольку это “данетка”, то, видимо, предполагается задавать вопросы на “да-нет”.
    На счёте в конце оказалась неотрицательная сумма?

  9. SALar написал:

    Огромное количество гипотез. Прекрасно. О большей части из них я не подумал, когда придумывал данетку.

    > buzin написал: 10 Сентябрь 2013 в 17:50
    > Тогда -$100 (овердрафт)
    Нет.

    > gdevgencih написал: 10 Сентябрь 2013 в 18:13
    > Может быть осталось 500$?
    > После того как система отвергла операцию к счету были добавлены 600$, которые с него не снимали.
    Нет.
    Примечание. Мне очень сложно представить такую ошибку в коде.

    > chip написал: 10 Сентябрь 2013 в 18:38
    > Вариант 0. Счет может уходить в минус. Остаток — $-100
    > Вариант 1. 600 зачислено, остальное снято. Остаток — 500 долларов
    > Вариант 2. Все зачисляется. Остаток — $2300
    > Вариант 3. 1-я попытка игнорируется, вместо снятия деньги зачисляются. Остаток $1700
    > Вариант 5. Снимается в рублях. Остаток: $800 - 900р
    Надо проапдейтить данетку. Счет дебитовый.

    Варианты 0 и 1 - смотри ответы выше.
    Вариант 2. - тогда непонятны разные ответы системы. Итого - “нет”
    Вариант 3 и 5. - хорошие гипотезы. Перепутать знак или валюту - это вполне, вполне. Но нет, не угадали.

  10. SALar написал:

    > nh написал:10 Сентябрь 2013 в 21:10
    > Гипотеза 1. На счёте осталось $800: снятие фактически не работает.
    > Гипотеза 2. На счёте осталось -$100: не работает проверка наличия достаточного количества средств.
    > Гипотеза 3. На счёте осталось $0: проверки наличия средств нет, но остаток всегда принудительно “поддерживается” не меньше нуля.
    > Гипотеза 4. На счёте осталось $800 + $400 + $500 = $ 1700: вместо операции снятия осуществляется операция пополнения.
    > Гипотеза 5. На счёте осталось -$700: то же, что в гипотезе 2, но при этом при попытке снять $600 деньги были сняты, несмотря на внешний отказ.
    > Гипотеза 6. На счёте осталось $2300: то же, что в гипотезе 4, но при этом при попытке “снять” $600 деньги были ошибочно начислены, несмотря на внешний отказ системы в проведении операции.
    > Гипотеза 7. На счёте осталось $800 - $600 = $200: система путает операции “снятие” и “отказ в снятии”.
    Дальше возможны более тонкие разновидности подобных сценариев…

    1. Я бы скорее, предположил некорректную работу с денормализованной БД. Ошибка часто встречающаяся. Пожалуй из того, что было предложено - наиболее правдоподобная версия. Но нет.
    (Сам на такое влетал в молодости.)

    2. Маловероятно. Очень сложно представить такой код, что в тригерах БД, что в коде снятия.
    Нет.

    7. Вероятнее чем 2, но менее вероятнее, чем 1.
    Нет.

    PS.
    > Лимит $500, потому что система слишком бажная, и лучше не доверять ей крупных операций. $500 на покушать хватит, а крупные покупки лучше делать как-нибудь понадёжнее.
    Это сложный вопрос, он на “Что, где, когда?”. Ответ неверный.

  11. SALar написал:

    Господа, в данетках можно проверять промежуточные гипотезы. Это как бы общее правило. Пользуйтесь. Т.е. нормальная серия может начинаться так:

    > В начале серии тестов на счету $800?
    Да.
    > Все снятия в долларах?
    Да.

  12. SALar написал:

    > nh написал: 10 Сентябрь 2013 в 21:23
    > Поскольку это “данетка”, то, видимо, предполагается задавать вопросы на “да-нет”.
    > На счёте в конце оказалась неотрицательная сумма?
    Прекрасный вопрос! Ответ - “Да”.

  13. adminby написал:

    А вопросы по одному задаются, или можно сразу пачкой?

    1. Снимались ли деньги со счета (вычитание со счета) вообще?
    2. Проверялось ли наличие необходимой суммы (на счету) перед снятием?
    3. Происходили ли операции со счетом (запись на счет) при превышении лимита снятия (первая попытка)?
    4. После 2 попытки случае остаток на счету составил 400$?
    5. После 3 попытки реального списания со счета не произошло (ошибка связана с проверкой лимита именно в 500$)?
    6. На счету осталось 400$?

  14. SALar написал:

    > 1. Снимались ли деньги со счета (вычитание со счета) вообще?
    Да.
    > 2. Проверялось ли наличие необходимой суммы (на счету) перед снятием?
    Нет.
    > 3. Происходили ли операции со счетом (запись на счет) при превышении лимита снятия (первая попытка)?
    Нет.
    > 4. После 2 попытки случае остаток на счету составил 400$?
    Да.
    > 5. После 3 попытки реального списания со счета не произошло (ошибка связана с проверкой лимита именно в 500$)?
    Произошло.
    > 6. На счету осталось 400$?
    Нет.

  15. adminby написал:

    При снятии суммы, превышающей остаток на счету, но меньшей или равной лимиту, отрицательное число не записывается, а записывается 0$ ?

  16. xBsd написал:

    $500 - распространенный лимит для ATM?

    система позволяет снятие дробных значений, $255.13?

    рассчитано только на целые значения?
    используется беззнаковый тип?
    сумма денег на счету что-то типа uint.MaxValue - 100?

  17. grokky написал:

    На счету осталось 300$?

  18. soapa написал:

    500 потому что стандартный банкомат не выдает более 50 купюр и в нем нет купюр номиналом менее 10$?
    На начало тестов сумма была 800?
    Во время выполнения тестов на счет были добавлены деньги?

  19. soapa написал:

    Кстати с лимитом - может списалось не 500, а 499.99?

  20. chip написал:

    На счету остался 0. Нет проверки перед снятием, но снять больше, чем есть на счету нельзя

  21. chip написал:

    вопросы:
    a) Если провести тест 4. Попытка снять $100 долларов. Результатом будет “Деньги сняты”?
    b) К наблюдаемому результату приводит всего одна ошибка в коде?

    P.S. Можно, конечно, делением пополам решить данную ситуацию за максимум 10 попыток (хотя если учесть, что все числа кратные 100, то число попыток резко сокращается), а потом придумывать гипотезу, но так неинтересно

  22. namor написал:

    Вариант $300 еще не рассматривался?
    Система при повторном снятии проверяет закешированное устаревшее значение баланса.

  23. penelopa написал:

    1. При попытке снять 500$ и снялось 500$?
    2. При попытке снять 500$ снялось 400$?
    3. Осталось 0$?

  24. penelopa написал:

    На счету осталось 0$? (при запросе большем, чем остаток, снимается весь остаток?)

  25. SALar написал:

    > adminby написал: 10 Сентябрь 2013 в 23:25
    > При снятии суммы, превышающей остаток на счету, но меньшей или равной лимиту, отрицательное число не записывается, а записывается 0$ ?
    Нет.

  26. SALar написал:

    > xBsd написал: 11 Сентябрь 2013 в 01:33

    > $500 - распространенный лимит для ATM?
    Да, но важна причина. Поэтому “Нет”.

    > система позволяет снятие дробных значений, $255.13?
    Да.

    > рассчитано только на целые значения?
    Нет. Центы тоже можно.

    > используется беззнаковый тип?
    Некорректный вопрос. Для автоинкремента используется беззнаковый тип, а для процентов - нет.

    > сумма денег на счету что-то типа uint.MaxValue - 100?
    Нет.

  27. SALar написал:

    > grokky написал: 11 Сентябрь 2013 в 02:47
    > На счету осталось 300$?
    Нет.

  28. SALar написал:

    > soapa написал: 11 Сентябрь 2013 в 05:04
    > 500 потому что стандартный банкомат не выдает более 50 купюр и в нем нет купюр номиналом менее 10$?
    Нет.

    > На начало тестов сумма была 800?
    Да
    > Во время выполнения тестов на счет были добавлены деньги?
    Нет

  29. SALar написал:

    > soapa написал: 11 Сентябрь 2013 в 08:07 [редактировать]
    > Кстати с лимитом - может списалось не 500, а 499.99?
    Нет

  30. SALar написал:

    > chip написал: 11 Сентябрь 2013 в 09:54
    > На счету остался 0. Нет проверки перед снятием, но снять больше, чем есть на счету нельзя
    Нет

  31. SALar написал:

    > chip написал: 11 Сентябрь 2013 в 09:59
    > вопросы:
    > a) Если провести тест 4. Попытка снять $100 долларов. Результатом будет “Деньги сняты”?
    > b) К наблюдаемому результату приводит всего одна ошибка в коде?
    Ну, наконец то вопрос нормального человека, а не тестировщика! “А давайте снимем еще!”
    а) Да
    б) И да и нет. Если поправить всего одну ошибку в коде, то ошибка исчезнет.

    > P.S. Можно, конечно, делением пополам решить данную ситуацию за максимум 10 попыток (хотя если учесть, что все числа кратные 100, то число попыток резко сокращается), а потом придумывать гипотезу, но так неинтересно
    Запрещено правилами данеток.

  32. SALar написал:

    > namor написал: 11 Сентябрь 2013 в 11:14
    > Вариант $300 еще не рассматривался?
    > Система при повторном снятии проверяет закешированное устаревшее значение баланса.
    Вариант не рассматривался, но “Нет”. (вариант хороший)

    > penelopa написал: 11 Сентябрь 2013 в 12:20
    > 1. При попытке снять 500$ и снялось 500$?
    Да
    > 2. При попытке снять 500$ снялось 400$?
    Нет

  33. nh написал:

    Гипотеза: на счету осталось $100. (Вариант возможен, если в качестве остатка средств на счёте берётся абсолютная величина от разницы между тем, что было, и тем, что сняли - остаток ведь не может быть отрицательным, вот мы его и “нормализуем”. Глупо, но встречаются и ещё более глупые программистские ошибки.)

  34. algo_dogs написал:

    Записали отрицательное число в беззнаковую переменную.
    Например так: 4294967196

  35. chip написал:

    Еще гипотеза, которая подходит под описанную ситуацию с учетом ответов на вопросы:
    Перепутаны переменные при снятии со счета: то есть остаток рассчитывается как (сумма_для_снятия)-(остаток), но с обратным знаком.
    тогда попытка 2. -(400-800)=400
    попытка 3. -(400-500)=100.
    Остаток 100.
    Но мне сложно представить, как можно так ошибиться в коде

  36. SALar написал:

    > algo_dogs написал:11 Сентябрь 2013 в 15:42

    > Записали отрицательное число в беззнаковую переменную.
    > Например так: 4294967196
    Близко.

  37. Llanie написал:

    А) Когда произвелось списание после выдачи 500$ — списание произошло с тестируемой карты?
    Б) База, в которой проверяется баланс, и база, в которой производится списание, — одна и та же?
    В) Комиссия за выдачу есть?
    Г) Были ли любые движения по счёту, кроме начисления 800$ в начале теста и списаний, произведённых в результате запросов на выдачу 1, 2 и 3? (начисление процентов, снятие блокировки и т.п.)

    Вопросы к бонусу:
    Лимит на снятие установлен на уровне карты/счёта (т.е. с этой карты/этого счёта в день можно снять не более 500), на уровне банкомата (зависит обычно от физических возможностей лотка и имеющихся номиналов), на уровне процессинга (для своих карт столько-то, для чужих столько-то)?
    Лимит на одно снятие или на снятия за день?

  38. adminby написал:

    > a) Если провести тест 4. Попытка снять $100 долларов. Результатом будет “Деньги сняты”?
    Ну, наконец то вопрос нормального человека, а не тестировщика! “А давайте снимем еще!”

    Если исходить из ответа:

    > 2. Проверялось ли наличие необходимой суммы (на счету) перед снятием?
    Нет.

    То снимать можно любые суммы, не превышающие лимита - бесконечно.

  39. SALar написал:

    > Llanie написал:11 Сентябрь 2013 в 16:37
    > А) Когда произвелось списание после выдачи 500$ — списание произошло с тестируемой карты?
    Со счета. Можно привязанного к карте.

    > Б) База, в которой проверяется баланс, и база, в которой производится списание, — одна и та же?
    Да.

    > В) Комиссия за выдачу есть?
    Неважно. Но, “Нет”.

    > Г) Были ли любые движения по счёту, кроме начисления 800$ в начале теста и списаний, произведённых в результате запросов на выдачу 1, 2 и 3? (начисление процентов, снятие блокировки и т.п.)
    Нет.

    > Вопросы к бонусу:
    > Лимит на снятие установлен на уровне карты/счёта (т.е. с этой карты/этого счёта в день можно снять не более 500), на уровне банкомата (зависит обычно от физических возможностей лотка и имеющихся номиналов), на уровне процессинга (для своих карт столько-то, для чужих столько-то)?
    > Лимит на одно снятие или на снятия за день?
    На одно снятие.

  40. SALar написал:

    >>> 2. Проверялось ли наличие необходимой суммы (на счету) перед снятием?
    >>Нет.
    >То снимать можно любые суммы, не превышающие лимита - бесконечно.
    Может быть так, может быть не так…
    Вопрос: «Сколько денег осталось на счете?»

  41. Llanie написал:

    Про то, на каком уровне установлен лимит почему-то ответа не было.
    Но он может быть связан как с физическими возможностями банкомата (там выше уже упоминали максимальный размер пачки банкнот), так и с более виртуальными ограничениями — например, для зарплатного банкомата лучше установить лимит поменьше, чтобы деньги ленились сразу все забирать, а снимали только действительно необходимую сумму, или по правилам платёжной системы, или по допустимым рискам банка на одну транзакцию.
    Кроме того, лимит мог быть установлен для воспроизведения конкретного бага с конкретными значениями.
    Ещё это может быть связано с магическими степенями двойки. Или просто подобран так, чтобы при правильной работе один раз можно было снять, если на счёт положить 800, а второй нет.

    Задача вообще задаётся о сферической банковской системе в вакууме или с реальными исходными? :)

  42. SALar написал:

    Зря я бонусный вопрос задал. “Ограничение задано исходя из политики борьбы с терроризмом и прочими преступлениями. При обмене валюты лимит тот же - 500. После этого нужно предъявить документ удостоверяющий личность. А банкоматом можно воспользоваться без предъявления (карточка на другое лицо).”

  43. adminby написал:

    1. Результат зависит от архитектуры процессора (сопроцессора)?
    2. Результат зависит от типа хранения данных в базе?
    3. Результат зависит от выбранной СУБД?
    4. Результат зависит именно от этого банкомата?
    5. После 3 попытки произошло переполнение?

  44. SALar написал:

    > 1. Результат зависит от архитектуры процессора (сопроцессора)?
    Нет.
    > 2. Результат зависит от типа хранения данных в базе?
    Скорее нет, чем да. Вопрос неконкретен.

    > 3. Результат зависит от выбранной СУБД?
    Нет.

    > 4. Результат зависит именно от этого банкомата?
    Нет. Точно “Нет.”
    > 5. После 3 попытки произошло переполнение?
    Явно нет. Так как просто прошла операция.
    Или я не понимаю, что такое переполнение.

  45. nh написал:

    > На счету осталось $100?

    Нет. И такой вопрос был.

  46. Llanie написал:

    > Ошибка произошла при вычитании 500$ из 400$?
    Ошибка произошла при выполнении третьей транзакции.
    > или
    > Ошибка произошла раньше, при определении необходимой операции по изменению остатка счёта?

    Нет.

  47. SALar написал:

    1. Попробуем вариант с ответами в тексте вопроса
    2. Данетка разгадывается до окончания дня программиста

  48. Llanie написал:

    > А. Если бы третьей операцией была попытка снять 450$, были ли бы деньги сняты?

    Да.
    > Б. Если ответ на предыдущий вопрос А. — “да”, то была ли бы сумма остатка такой же, как после снятия 500$?

    Нет
    > В. Если ответ на вопрос Б. — “нет”, то была ли бы сумма остатка на 50$ меньше?

    Вопрос подразумевает двоякую трактовку.

    Если снимать $500, то остаток на $50 меньше

  49. soapa написал:

    > В памяти хранится не 800, а какой-то результат encode(800), который равен ну допустим 349758731
    > И ошибка в том, что снимается не encode(400) и encode(500), а 400 и 500?

    Нет

Оставьте комментарий

Вы должны войти, чтобы оставить свой комментарий.