TGViewer
Никита Федькин - мысли, заметки, анонсы Никита Федькин - мысли, заметки, анонсы @nixel2007_thoughts · 2.88K subscribers
Post #279 2.58K
Представьте примерно следующий код:

Ключ = Новый Структура("Поле1, Поле2", "123", "456");
Карта.Вставить(Ключ, 1);

Ключ2 = Новый Структура("Поле1, Поле2", "789", "987");
Карта.Вставить(Ключ2, 2);

Значение = Карта.Получить(Ключ2);

Вроде ничего сложного, да? Сделали два ключа, положили по ним значение в соответствие карту, затем получили значение по второму.

Пример утрированный, эти операции размазаны по коду, но смысл такой.

Так вот. Как думаете, что будет в переменной Значение? По идее двойка, да?

По идее да. Двойка. И так и было примерно в 99.9% случаев. А в 0.01% в Значении было... Неопределено.

НедоумевающийДжекиЧан.джпг

Что, почему, как? Херня эта ваша джава, да?

Как и в большинстве случаев в программировании проблема оказалась в программисте.

Интерфейсы часто помимо, собственно, сигнатуры метода, содержат еще некоторую договоренность или контракт, описанный в документации к интерфейсу. Например, в случае Comparable есть требование возвращать -1, 0 или 1 в качестве результата метода compareTo для значений "меньше", "равно" или "больше" в плане сравнения порядка/сортировки двух объектов. Или рекомендация возвращать 0, если объекты равны между собой по equals, что действительно звучит логично - равные объекты и упорядочиваться должны одинаково.

Но есть и еще одно требование - если А > Б, то обязательно должно выполняться Б < А. От перемены мест слагаемых и все такое прочее.

Душный Дотошный читатель мог обратить внимание, что моя на скорую руку написанная реализация compareTo сранивала хэш-коды на строгое больше и меньше и задаться вопросом: "А что будет, если хэш-коды у двух разных объектов будут одинаковыми? Это валидная ситуация?". И будет абсолютно прав в своей дотошности. Ситуация валидная, а я лопух, нарушивший контракт А > Б = Б < А

Т.к. метод сортировки применяется в ConcurrentSkipListMap для построения индекса, два объекта, которые при сравнении друг с другом с разных сторон давали разные ответы, приводили к ошибкам позиционирования в индексе. И вместо нахождения в индексе адреса нужного значения в дереве из двусвязных списков, индекс врезался в null.

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

Можно было бы подумать, что это все жабо-проблемы, и в этом нашем 1С такого не может быть. Какие у нас интерфейсы, какие контракты?

А вот и нет. Есть у нас интерфейсы, и есть контракты. Не важно, какую библиотеку вы используете: Библиотеку стандартных подсистем с ее миллионом общих модулей и вязанкой "переопределяемых" методов, или, к примеру клевую библиотеку для сериализации SerLib1C от Артема Кузнецова (не реклама, честно, просто вспомнилось :) ) - автор может закладываться на какое-то ваше адекватное поведение в коде переопределяемых обработчиков. Хороший автор еще напишет об этом в документации.

Вот такое вам длиииииииинное субботнее чтиво.
Всем добра и RTFM!
GitHub fix: исправлено нарушение контракта compareTo by EightM · Pull Request #2745 · 1c-syntax/bsl-language-server контракт "x.compareTo(…y)) == -signum(y.compareTo(x))" не выполняется при сравнении объектов с одинаковым hashcode Общие Ветка PR обновлена из develop Отладочные, закомментированные и ...
  • 👍 22
  • 🔥 2
More from @nixel2007_thoughts
  1. Oct 15, 2026Компьютерики шутят (с)
  2. Oct 11, 2026Когда устал пилить опенсорс, подобрел и решил открыть свой магазин одежды.
  3. Sep 28, 2026Вторую картинку в посте потерял. Вот так менять/задавать пароль.
  4. Sep 28, 2026Если вы можете прочесть этот пост, то вероятно, ваш телефон находится, кхм-кхм, за границе…
  5. Sep 28, 2026video post
  6. Sep 28, 2026#анонс Полишинеля Я разрываюсь между двумя фразами на анонс, пускай будут обе: 1. Мы строи…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →