Банкомат

  • 9
  • Недоступна
Разберись, как работает программа. Во время тестирования лог содержит следующее: ..... Добавляем 1000, на счету 1000 Тратим 100, на счету 800 Тратим 100, на счету 800 Тратим 100, на счету 800 Тратим 100, на счету 700 ..... Создан баг: деньги не правильно списываются со счета. Твоя задача:
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (243)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Айбелив Айкенфлаев
Уровень 28, Москва, Россия
20 июня, 18:53
Когда сделал так, чтобы деньги прибавлялись быстрее чем тратились, в консоль было так приятно смотреть, будто это реальные уведомления банка
Reviksedy
Уровень 35
18 марта, 14:27
два последних требования прямо говорят что делать
Nikolay Veselov
Уровень 41, Stavropol, Russian Federation
16 марта, 15:21
Сначала сделал через синхронизацию на классе BankAccount, валидатор не принял, хотя работа программы корректная. Остался вопрос, в итоге так можно было делать или нет?
NonGrata
Уровень 34, Israel
27 марта, 17:34
Я в методе run() поставил синхронизацию на BankAccount.class и визуально работа даже лучше выглядит чем через решение, любопытно если все таки это объективно корректно или нет,
Anonymous #2856674 Software Developer
27 апреля, 05:07
Если ты на Run поставил синхронизацию на мютекс BankAccount.class , значит ты вообще заблочил одновременное выполнение потоков - ни один из них не может запуститься, пока работает первый Собственно смысл потока вообще исчезает
NonGrata
Уровень 34, Israel
27 апреля, 18:13
Тоже верно, если исходить из логики что карта может одновременно использоваться в разных местах и для разных целей (типа одновременно снятия денег с разных мест + в то же время что бы туда деньги заходили тоже)
Лик Вадим
Уровень 35, Москва, Russian Federation
9 марта, 09:50
Получить верное решение в этой задаче легко, а вот понять почему это решение верно - сложнее. Я в итоге получил два ПОЧЕМУ, в которых пока не разобрался: 1.В задаче есть два метода withdraw с разными входящими параметрами: withdraw(String money) и withdraw(BigDecimal money) при этом работа первого заключается в вызове второго из своего тела с преобразованием входящего параметра money из String в BigDecimal. та же самая картина и с deposit. Я намеренно не синхронизировал все методы withdraw и deposit. А только первые из них, с входящим параметром money типа String. Программа при этом работала корректно. Моя логика была проста: если синхронизирован первый метод, а второй вызывается из его тела, то пока работает первый в режиме синхронизации, никакая сторонняя нить, кроме той что уже заняла мьютекс объекта в первом не сможет работать с ним во втором методе, даже если второй метод не синхронизирован. Иными словами я считал ( и считаю) что синхронизировать только методы withdraw(String money) и deposit(String money) в данном конкретном случае было бы достаточно. И корректно работающий код был этому подтверждением. Валидатор с этим не согласился. Вопрос почему? Это потому что уместен подход - синхронизируй все что изменяет общие данные, так правильно и точка. Или я в самом механизме синхронизации что то не верно понял? 2. Я намеренно не добавил к переменной account слово volatile. Думал валидатор такое решение не примет. Но его он как раз пропустил. Исходя из понимания теоретической части : Если переменной , значение которой могут менять разные потоки не присвоить volatile, то возможны ситуации, когда значения этой переменной могут храниться в не общедоступной кеш памяти, а потому изменения, вносимые одной из нитей в значение этой переменной - другии нити могут не увидеть. Что бы избежать этого - нужно объявить эту переменную volotile.В моем понимании переменная account как раз подпадает под этот случай, но валидатор считает иначе. Почему?
SWK
Уровень 16
6 апреля, 11:01
1. Это работает. Но это очевидно избыточно. Поскольку методы со строками сами ничего не делают, кроме преобразования параметров, они не могут что-то нарушить. А могут нарушить основные. Их и надо синхронизировать. 2. Тоже не понимаю.
Andrey
Уровень 36, Санкт-Петербург, Россия
23 апреля, 13:15
1. Соглашусь с @SWK 2. volatile замедляет программу. А если у нас все методы, которые могут повлиять на состояние аккаунта - synchronized, то и необходимость в volatile отпадает (накидайте плюсов для ачивки пожалуйста 🙃)
Максим Белоусов
Уровень 18, Москва, Россия
7 декабря 2021, 11:23
Отличная задача в которой повторяем огромные числа BigDecimal, делегирование в методах и паттерн producer-consumer. Очень понравилось!
Sergey Kornilov
Уровень 38, Petropavlovsk, Казахстан
6 ноября 2021, 10:52
Всего эту задачу решили 23088 учеников.
Игорь Евгеньевич
Уровень 41, Хабаровск, Россия
14 октября 2021, 10:57
public synchronized void deposit(String money) { deposit(new BigDecimal(money)); } public synchronized void withdraw(String money) throws NotEnoughMoneyException { withdraw(new BigDecimal(money)); } В этих двух последних методах класса BankAccount в качестве аргумента передаётся строка. Далее они вызывают такой же метод принимающий BigDecimal и передают в него new BigDecimal с этой строкой. Вопрос! Как это работает?
Anonymous #2583212
Уровень 40
21 октября 2021, 10:44
Это рекурсия. Почитайте об этом
Dmitry Noskov
Уровень 49, Москва, Russian Federation
24 октября 2021, 17:00
это не рекурсия, это перегрузка методов:
public void deposit(BigDecimal money) {};
public void deposit(String money) {};
с точки зрения JVM это два разных независимых друг от друга метода. рекурсия была бы, если бы метод в своём теле вызывал себя.
Anonymous #2583212
Уровень 40
25 октября 2021, 04:00
Вы правы, я ошибся.
Денис Измайлов Инженер- программист в CloudFactory
2 сентября 2021, 07:52
И снова , условие: "Создан баг: деньги не правильно списываются со счета. Твоя задача: найти и исправить ошибку" так почему синхронизация по объекту в тредах НЕ решение, а синхронизация методов решение ? ОБА решения удовлетворяют поставленной задаче. Да. В реквайрементах описано про методы. НО ЭТО НЕ УСЛОВИЕ ЗАДАЧИ!!! ё-маё. ОТКУДА "реквайремнеты" вытекают из условия ?!
SWK
Уровень 16
6 апреля, 11:13
Дык, синхронизация _чего_ "по объекту в тредах"? Вызова тех же методов? Один фиг, ключевое место - методы.
Torba Z Dimom
Уровень 23, Киев, Украина
6 августа 2021, 22:17
Как и в многих предыдущих задачах самое сложное("долгое") - понять что делает програма. и чем дальше тем больше строк.... хорошая тренировка, но вот времени жрет вагон.
Андрей Dungeon Master
9 ноября 2021, 09:41
вагон? пфф, ищешь метод, который отвечает на съем и взнос денег и синхронизируешь, 20 секунд решал задачу
Саня
Уровень 31, Москва
29 июня 2021, 10:43
Вот специально не стал перед отправкой синхронизировать deposit() -- и валидатор конечно же ругнулся -- а по факту всё работает правильно. Ну и зачем тогда этот метод синхронизовывать??
Галина
Уровень 19, Москва, Россия
21 сентября 2021, 10:25
Я тоже не очень поняла зачем его синхронизировать, если там отдельная нить создается для вызова deposit().
Галина
Уровень 19, Москва, Россия
21 сентября 2021, 10:26
Вроде как надо синхронизировать всё, что использует общие ресурсы. Но если для этого одна нить, то зачем ее синхронить?
NonGrata
Уровень 34, Israel
27 марта, 17:37
Да, я тоже не понял, в чем проблема если деньги будут заходить на счет, в то же время пока их тратят? Тогда бы не пришлось видеть надпись недостаточно средств...
SWK
Уровень 16
6 апреля, 11:11
В том, что одна сумма пропадёт: 1 читает размер счёта. 2 читает размер 1 считает, сколько должно получиться после операции. 2 считает, сколько должно получиться после операции. 1. записывает результат. 2. записывает результат. Сумма, которую вносила/снимала 1я нить, пропала.