Комментарии 29
Java-лузер ¯_(ツ)_/¯
В основном на питоне пишу, но, думаю, что и в питоне таких деталей не знаю.
Конечно, считаю необходимым знать такие вещи, но в коде аппликух средних компаний ни разу таких заумных конструкций не встречал.
… и у тебя возникает необходимость использовать класс из этой библиотеки в качестве ключа в HashMap ...
Это ж над чем нужно трудиться, чтобы такая «необходимость» возникла???
Интересно, кто ваши клиенты… можно список, чтобы по возможности избегать?
Кхм. Расчет в методе без использования переданного аргумента? Взаимодействие producer-consumer, где isLock ставится только в true
, но никогда — в false
? Если уж в тестах у вас ошибки, то в рабочем не лучше. Не-не-не, такой код поддерживать я не хочу.
К сожалению, разработчики написали плохую хеш-функцию, и наблюдается значительная коллизия ключей. Метод equals() переопределен корректно. Какую алгоритмическую сложность поиска значения по ключу стоит ожидать?
Вы, конечно, ожидаете, что с Java 8 будет O(log n). Но это возможно только в том случае, если разработчики сделали свои объекты Comparable
и корректно реализовали compareTo
. Что было бы наивно ожидать от разработчиков, которые реализовали плохую хэш-функцию. Ни разу в жизни не видел объекта с плохой (но корректной) хэш-функцией и правильным compareTo
одновременно. Вы видели?
Но скорее всего, в программе авторства разработчиков, которые не осилили написание хэш-функции, смотреть на ассимптотическую сложность бессмысленно, поскольку производительность можно испортить куда более эффективными способами
Должен ли класс, который планируется использовать в качестве ключа HashMap, быть полностью immutable?
Тут очень много вопросов. Начиная с того что понимать под immutable класс. Можете дать определение? Я знаю, что лучшие умы OpenJDK обсуждали этот термин долго и горячо, когда ввели вот эти все List.of
и собирались их описать в документации. В итоге вообще отказались от слова immutable. Вот к примеру java.lang.String immutable или нет?
Также в "правильном" ответе ничего не написано про контракт Comparable. А если ключ реализует Comparable, но после изменения объекта результат сравнения получается другой? HashMap может сломаться.
Я бы ответил, что для любого объекта, используемого в качестве ключа (в том числе необязательно помещённого в Map, но и переданного в containsKey и т. д.), результат hashCode должен сохраняться на протяжении использования, а также для любой пары объектов, используемых в качестве ключа, результат equals и compareTo (при наличии) должен тоже сохраняться на протяжении использования. А что означает слово immutable — наплевать.
Ты разрабатываешь часть системы, которая выполняет различные финансовые операции. Какие типы могут подойти для выполнения таких операций?
И к этому вопросу много вопросов. Типа Int
в стандартной библиотеке Java вообще нет, но допустим это особенность формы опроса и имелся в виду примитивный int
. Почему можно его использовать? Человек, у которого больше двух миллиардов рублей на счету, будет очень недоволен. Деление двух интов всегда округляется вниз, хотя вы пишете, что округлений нет. Наконец, любое число, представимое в int
, представимо и в double
с той же самой точностью. То есть любую операцию, которую вы можете сделать на int
, вы можете сделать на double
с не меньшей точностью. Причём у вас будет более точный результат деления и меньше рисков переполнения. Почему int
считается правильным ответом, а double
нет — совершенно неясно.
Нет, я понимаю стандартную мантру "используйте BigDecimal", но блин, вопрос-то надо правильно формулировать.
Даже в основных валютах финансовые операции в банковских системах могут выполняться пакетом или с рычагом и хранятся, в итоге, далеко не в целых копейках
О бумагах я уж вообще не говорю
На седьмой вопрос мой ответ: у меня глаза текут от этого ужасного кода. Используйте неизменяемые кортежи, лесом синхронизацию.
На восьмой вопрос мой ответ: не мучайте киску. Если вам нужен putIfAbsent, берите CopyOnWriteArraySet и радуйтесь. Если вы по несчастью застряли с synchronizedList, рефакторьте код, это в любом случае опасная фигня (например, стримы от неё небезопасны, я дописал это в документации). Если уж совсем припёрло, почитайте документацию, там написано, что надо использовать в качестве монитора для синхронизации дополнительных операций. Помнить это наизусть необязательно. Про synchronizedList надо помнить одну вещь: что его лучше избегать и использовать крайне осторожно.
На девятый вопрос мой ответ: используйте SynchronousQueue из стандартной библиотеки. Вы всё равно не сделаете лучше. Все четыре предложенные реализации неустойчивы против повторного вызова producer
. В этом плане смешно видеть умные слова в ответе "что позволяет потоку писать данные достаточно быстро". Как он может писать достаточно быстро, если дизайн класса не предполагает перекачки более одного значения? Такой код в серьёзном продакшне недопустим. Не надо изобретать велосипеды.
На десятый вопрос мой ответ: давайте всё-таки хорошо подумаем и попытаемся избавиться от циклических зависимостей между компонентами перед тем как делать вот это.
Ты их не слушай, ты lany слушай — вот он действительно стоящие вещи говорит, а эта статейка — сплошноё позёрство и попытки выгрести из говнокода хоть чуть пользы…
Ещё где-то на хабре обитал Шипилёв (можно в ютубчике его выступления на Joker и JPoint посмотреть) — он тоже полезные вещи про это всё говорит.
Задача 8 ад. Ответил неправильно и долго не мог понять, чем другие локи не угодили.
Через 5 минут увидел, что поле то public
. Не, это серьёзно? Сейчас ещё есть люди, кто на автомате все поля private/protected/package private не делает?
Ну т.е. использование synchronizedList
и не-создание копии входящего списка, видимо, было мало для bad practice
И после таких вопросов:
Сделать шаг к вершине и прокачаться на интересных задачах ты можешь в команде НСПК.
Очень интересные задачи. Мукачайтесь с ними сами
Ещё замечания по поводу восьмого вопроса, который про putIfAbsent
, чтобы всё лежа более-менее в одном месте:
• смысл в потокбезопасной обёртке, если оборачиваемый список к нам приходит извне, и по утёкшей ссылке можно вполне себе изменять состояние списка?
• я сам не увидел, но public-поле вообще позволяет подпихнуть что угодно вместо синхронизированного списка.
• Один из ответов вообще не компилируется
class ModifiedList<E> {
public final List<E> syncList;
public ModifiedList(List<E> list) {
this.syncList = Collections.synchronizedList(list);
}
public boolean putIfAbsent(E item) {
boolean absent = !syncList.contains(item);
if (absent)
lisyncListst.add(item);
return absent;
}
}
У нас нет переменной по имени lisyncListst
, а не "Метод не синхронизирован в принципе, может возникнуть race-condition".
Вообще, я раза три думал перестать писать комментарий, но тут и более умные люди прошлись по тесту, пусть будет этот комментарий хотя бы про эту задачу.
— отзывы о компании удручают
— кандидата в итоге не взяли
Открываем первую задачку:
этот класс ты планируешь использовать в качестве ключа
Точно "этот класс"? Может быть всё-таки "объекты этого класса" или "объекты этого типа"?
Не, серьёзно, поработайте над формулировками.
Я не то, что придираюсь. Но просто если я буду использовать в качестве ключа класс (.class), то очень понятно, что дальше будет происходить, и кажется это не то, чего ожидают авторы вопроса.
Терпимо, кроме формулировки первого вопроса и использования слова замок.
Java-чемпион или Java-лузер: тест для разработчиков