Душные вопросы на java-стажировке
1194
79
Aragorn_ сказал(а):↑В чем проблема? У тебя может быть Map.
У тебя может быть HashSet, где будет использоваться твой hashcode...
Нажмите, чтобы раскрыть...1) Так не в JOintable, а в HashSet.
2) Еще раз - объекты, у которых все поля одинаковы - эквивалентны. ID в виде инкрементной циферки - суррогатный, и в хороших практиках он не используется в хэшкоде, хотя иногда в этом есть необъодимость.
Aragorn_ сказал(а):↑Поэтому в хибернейте есть такое решение(оно суперредкое и относительное мемное), что есть смысл установить константное int значение hashcode. И если использовать это с умом, не набивая хэшмапу миллионами данных(а например туда записывать до 10 объектов), чтобы сильно не повлиять на перформанс, тогда все будет ок.
Нажмите, чтобы раскрыть...Это бред чистой воды.
Aragorn_ сказал(а):↑Я тебе дал условие - ентити имеет только id в виде unique значения, значит id(которое null) + любое поле дает в любом случае большой шанс совпадения хэшкодов, но при этом не управляемое(значит безсмысленное).
Нажмите, чтобы раскрыть...Зачем тебе 2 абсолютно одинаковых объекта в бд с разными ид? Для таких вещей делаются композитные уникальные индексы, в состав которых добавляются все поля таблицы, кроме ид. И так же в хэшкод добавляют все поля объекта, кроме ид.
И, опять же, если ты к этим полям добавишь еще и ид - логика нигде не пропадет.
Aragorn_ сказал(а):↑Ну да ты прав.
1. В том, что джава читабельней большинства языков
Минималистичный язык, че за кринж ты написал?
Конечно, если сравнивать с С++ - минималистичный. Если сравнивать со всеми частоиспользуемыми - JS, Go, PHP, Python, так это они минималистичны, а не Джава.
И если ты по такому принципу определяешь сложность языка и его стэка, то удачи остаться вкатывальщиком без работы))0
Нажмите, чтобы раскрыть...Любой язык сложнее java, да она многословна, но простая. В тех же python js много неоднозначных и неочевидных конструкций.
AMDkrolyan сказал(а):↑
Если у тебя join значит у тебя уже есть id
Нажмите, чтобы раскрыть...у тебя id по зависящей сущности. ну т.е.
хибернейт делает:
insert into(id, name, relatedEntity_id) values (null, "a", 3)
ну или с join таблицей не суть.
на данном этапе тебе не нужен id main сущности чтобы добавить к нему relatedEntity.
Aragorn_ сказал(а):↑С каких пор проверка эквивалентности по id не корректна?) Это уникальное значение
Нажмите, чтобы раскрыть...С тех пор, что ид - показатель уникальности, а не эквивалентности. Если у меня есть юзер с именем tDmx и мылом x@mail.ru с id 1, и я его сравниваю с другим юзером с именем tDmx и мылом x@mail.ru и id = null, equals должен показать, что это одинаковые объекты. Твой автоинкрементный ид - суррогатный, он не имеет, по сути, никакого отношения к предметной области. Это циферка для удобства.
Aragorn_ сказал(а):↑у тебя id по зависящей сущности. ну т.е.
хибернейт делает:
insert into(id, name, relatedEntity_id) values (null, "a", 3)
ну или с join таблицей не суть.
на данном этапе тебе не нужен id main сущности чтобы добавить к нему relatedEntity.
Нажмите, чтобы раскрыть...И вообще, ты можешь генерировать id на уровне java кода.
Pudgewerksaw сказал(а):↑Любой язык сложнее java, да она многословна, но простая. В тех же python js много неоднозначных и неочевидных конструкций.
Нажмите, чтобы раскрыть...какой кринж.
я так понимаю ты какой-то вкатывальщик в условный python, который не понимает банальных вещей, потому что не умеет программировать, в итоге открыл java, а там конечно же, каждая деталь описана в книгах и javadoc'е, и ты решил что поэтому Java проще?
Java проще для изучения программирования может? Ну да, и не проще, а просто лучше, потому что она граммотней чем те языки.
Aragorn_ сказал(а):↑у тебя id по зависящей сущности. ну т.е.
хибернейт делает:
insert into(id, name, relatedEntity_id) values (null, "a", 3)
ну или с join таблицей не суть.
на данном этапе тебе не нужен id main сущности чтобы добавить к нему relatedEntity.
Нажмите, чтобы раскрыть...речь шла у тебя, о сете (который вставляется через select или join запрос), где нужен хеш-код, а значение хеша ты хочешь вычитывать на основе id
тут проблем думаю нет ?
лучше всегда юзать лист, но допустим нужна имплементация где два одинаковых объекта не могут попасть, если id нет, значит логично, что сравнивать надо по всем полям, либо придумывать version\checksum посредством uuid и т.д., тут уже смотря какая задача
tDmn/// сказал(а):↑С тех пор, что ид - показатель уникальности, а не эквивалентности. Если у меня есть юзер с именем tDmx и мылом x@mail.ru с id 1, и я его сравниваю с другим юзером с именем tDmx и мылом x@mail.ru и id = null, equals должен показать, что это одинаковые объекты. Твой автоинкрементный ид - суррогатный, он не имеет, по сути, никакого отношения к предметной области. Это циферка для удобства.
И вообще, ты можешь генерировать id на уровне java кода.
Нажмите, чтобы раскрыть...ты меня заговариваешь со своим equals. Ну да ты прав в первом абзаце, но к чему это если речь шла про hashcode? Ты просто начал говорить про equals, ну и я может где-то оговорился. Забудь про equals, я про него ничего не говорил изначально.
что значит генерировать на уровне Java?
Aragorn_ сказал(а):↑какой кринж.
я так понимаю ты какой-то вкатывальщик в условный python, который не понимает банальных вещей, потому что не умеет программировать, в итоге открыл java, а там конечно же, каждая деталь описана в книгах и javadoc'е, и ты решил что поэтому Java проще?
Java проще для изучения программирования может? Ну да, и не проще, а просто лучше, потому что она граммотней чем те языки.
Нажмите, чтобы раскрыть...Фишка в том что в Java нет ничего, никаких деталей. Вся сложность языка зарыта глубоко в исходниках jvm, знать как работает которая тебе вообще нафиг не нужно, иначе зачем ты вообще пишешь на джава. И это не делает язык плохим, плохим его делает наличие jvm без которого он бы и не был таким простым. Простота и отсутствие сахара это главная фишка джава, можно никогда в жизни не писать на java, но открыть ее код и полностью его понять.
Aragorn_ сказал(а):↑ты меня заговариваешь со своим equals. Ну да ты прав в первом абзаце, но к чему это если речь шла про hashcode? Ты просто начал говорить про equals, ну и я может где-то оговорился. Забудь про equals, я про него ничего не говорил изначально.
Нажмите, чтобы раскрыть...Хэшкод является методом повышения производительности equals. Его суть похожа на вероятностный тест числа на простоту - если хешкод одного объекта равен хэшкоду другого объекта, то эти объекты (внимание) эквивалентны, но это не точно. Хотите знать точно? Идите в equals.
Если твой хэшкод работает по-другому: значит, и твой equals работает неверно. Поэтому делать хэшкод только по id, или, тем более, делать его константой - грубая ошибка в абсолютном большинстве случаев (хоть и не всегда).
Aragorn_ сказал(а):↑что значит генерировать на уровне Java?
Нажмите, чтобы раскрыть...Пункт 3.5, например (UPD если я правильно помню)
AMDkrolyan сказал(а):↑лучше всегда юзать лист, но допустим нужна имплементация где два одинаковых объекта не могут попасть, если id нет, значит логично, что сравнивать надо по всем полям, либо придумывать version\checksum посредством uuid и т.д., тут уже смотря какая задача
Нажмите, чтобы раскрыть...Нет, как раз лучше использовать Set)
опять вы про сравнения, если речь про hashcode который используется для бакета и подсчета индекса в хэштаблице)
сравнение объектов тут вообще не имеет значения.
сравнение в мапе идет map.get(obj1).equals(map.get(obj2) & obj1.equals(obj2). Если у тебя там хэшкоды будут равны, тебе насрать, всеравно сравнение корректно пройдет.
НО речь шла просто про hashcode, где ты плюешь на то, что у тебя все условные 10 объектов ссылаются на один bucket в хэшмапе. ВСЬО)
Aragorn_ сказал(а):↑Нет, как раз лучше использовать Set)
опять вы про сравнения, если речь про hashcode который используется для бакета и подсчета индекса в хэштаблице)
сравнение объектов тут вообще не имеет значения.
сравнение в мапе идет map.get(obj1).equals(map.get(obj2) & obj1.equals(obj2). Если у тебя там хэшкоды будут равны, тебе насрать, всеравно сравнение корректно пройдет.
НО речь шла просто про hashcode, где ты плюешь на то, что у тебя все условные 10 объектов ссылаются на один bucket в хэшмапе. ВСЬО)
Нажмите, чтобы раскрыть...сам придумал что-то, сам подловил
во-первых, где пример того, что лучше использовать Set, тут уже идет привязка к генерации hashcode к конкретной jvm.
во-вторых, если ты не переопределишь hashcode, его jvm сгенерирует автоматически, что тоже зависит от имплементации jvm
Aragorn_ сказал(а):↑Нажмите, чтобы раскрыть...Залез посмотреть про стратегии генерации идентификаторов и наткнулся:
Java Persistence API и Hibernate, глава 10.3.2Реализовать методы equals() и hashCode() можно разными способами. Но помните, что, переопределяя equals(), обязательно следует переопределить hashCode(), чтобы они вели себя согласованно. Если два экземпляра равны, они должны иметь одинаковые значения хэша. Кажется, что в equals() достаточно было бы сравнивать только свойства идентификаторов в базе данных, как правило, представляющих суррогатные первичные ключи. По сути, если два экземпляра Item имеют одинаковое значение идентификатора, возвращаемое методом getId(), они представляют одну сущность. Если метод getId() возвращает null, это временный экземпляр Item, который еще не был сохранен. К сожалению, это решение имеет один большой недостаток – Hibernate не присваивает идентификаторов, пока экземпляры не станут хранимыми. Если перед сохранением добавить временный экземпляр в коллекцию Set, после сохранения его хэш изменится, пока он все еще будет находиться в коллекции Set. Это противоречит контракту коллекции java.util.Set и нарушит ее работу. В частности, из-за этой проблемы становится бесполезным использование каскадной передачи хранимого состояния в отображаемых связях на основе множеств. Мы выступаем решительно против использования равенства идентификаторов в базе данных. Чтобы подобраться к решению, мы советуем познакомиться с понятием бизнесключа. Бизнес-ключ – это свойство или их комбинация, уникальное для каждого экземпляра с одинаковым идентификатором в базе данных. По сути, это естественный ключ, который можно было бы использовать взамен суррогатного первичного ключа. В отличие от естественного первичного ключа, к бизнес-ключу не предъявляется требование его неизменности – достаточно и того, чтобы он изменялся редко. Мы утверждаем, что практически каждый класс сущности должен обладать бизнес-ключом, даже если он включает в себя все свойства этого класса (что вполне подходит для некоторых неизменяемых классов). По каким признакам ваши пользователи будут различать A, B и C в списке товаров на экране? Это свойство или их комбинация и будет вашим бизнес-ключом. Бизнес-ключ – это то, что по мнению пользователя уникально идентифицирует конкретную запись, тогда как суррогатный ключ – это то, на что полагаются приложение и СУБД. Наиболее вероятно, что свойство или свойства, составляющие бизнес-ключ, будут иметь в схеме базы данных ограничение UNIQUE.
Pudgewerksaw сказал(а):↑Фишка в том что в Java нет ничего, никаких деталей. Вся сложность языка зарыта глубоко в исходниках jvm, знать как работает которая тебе вообще нафиг не нужно, иначе зачем ты вообще пишешь на джава. И это не делает язык плохим, плохим его делает наличие jvm без которого он бы и не был таким простым. Простота и отсутствие сахара это главная фишка джава, можно никогда в жизни не писать на java, но открыть ее код и полностью его понять.
Нажмите, чтобы раскрыть...Че тут написано?
СпойлерtDmn/// сказал(а):↑Пункт 3.5, например (UPD если я правильно помню)
Нажмите, чтобы раскрыть...Так это хрень которую есть смысл юзать только когда твоей базы нет в списке:
Hibernate supports all the major RDMS. Following are the list of database engines supported by Hibernate:
- HSQL Database Engine
- DB2/NT
- Oracle
- Microsoft SQL Server Database
- Sybase SQL Server
- Informix Dynamic Server
- MySQL
- PostgreSQL
- FrontBase
tDmn/// сказал(а):↑Хэшкод является методом повышения производительности equals. Его суть похожа на вероятностный тест числа на простоту - если хешкод одного объекта равен хэшкоду другого объекта, то эти объекты (внимание) эквивалентны, но это не точно. Хотите знать точно? Идите в equals.
Если твой хэшкод работает по-другому: значит, и твой equals работает неверно. Поэтому делать хэшкод только по id, или, тем более, делать его константой - грубая ошибка в абсолютном большинстве случаев (хоть и не всегда).
Нажмите, чтобы раскрыть...Хоть и не всегда? Лол так в чем спор? Где я написал что это нормально в БОЛЬШИНСТВЕ случаев?))) Спор ради спора
tDmn/// сказал(а):↑Залез посмотреть про стратегии генерации идентификаторов и наткнулся:
Java Persistence API и Hibernate, глава 10.3.2Реализовать методы equals() и hashCode() можно разными способами. Но помните, что, переопределяя equals(), обязательно следует переопределить hashCode(), чтобы они вели себя согласованно. Если два экземпляра равны, они должны иметь одинаковые значения хэша. Кажется, что в equals() достаточно было бы сравнивать только свойства идентификаторов в базе данных, как правило, представляющих суррогатные первичные ключи. По сути, если два экземпляра Item имеют одинаковое значение идентификатора, возвращаемое методом getId(), они представляют одну сущность. Если метод getId() возвращает null, это временный экземпляр Item, который еще не был сохранен. К сожалению, это решение имеет один большой недостаток – Hibernate не присваивает идентификаторов, пока экземпляры не станут хранимыми. Если перед сохранением добавить временный экземпляр в коллекцию Set, после сохранения его хэш изменится, пока он все еще будет находиться в коллекции Set. Это противоречит контракту коллекции java.util.Set и нарушит ее работу. В частности, из-за этой проблемы становится бесполезным использование каскадной передачи хранимого состояния в отображаемых связях на основе множеств. Мы выступаем решительно против использования равенства идентификаторов в базе данных. Чтобы подобраться к решению, мы советуем познакомиться с понятием бизнесключа. Бизнес-ключ – это свойство или их комбинация, уникальное для каждого экземпляра с одинаковым идентификатором в базе данных. По сути, это естественный ключ, который можно было бы использовать взамен суррогатного первичного ключа. В отличие от естественного первичного ключа, к бизнес-ключу не предъявляется требование его неизменности – достаточно и того, чтобы он изменялся редко. Мы утверждаем, что практически каждый класс сущности должен обладать бизнес-ключом, даже если он включает в себя все свойства этого класса (что вполне подходит для некоторых неизменяемых классов). По каким признакам ваши пользователи будут различать A, B и C в списке товаров на экране? Это свойство или их комбинация и будет вашим бизнес-ключом. Бизнес-ключ – это то, что по мнению пользователя уникально идентифицирует конкретную запись, тогда как суррогатный ключ – это то, на что полагаются приложение и СУБД. Наиболее вероятно, что свойство или свойства, составляющие бизнес-ключ, будут иметь в схеме базы данных ограничение UNIQUE.
Нажмите, чтобы раскрыть...В кратце - используйте например UUID как доп. бизнес ключ. Об чем мы тоже уже говорили))
tDmn/// сказал(а):↑Суть в том, что у тебя вопрос без вопроса.
Нажмите, чтобы раскрыть...вопросов нет, забудь))
AMDkrolyan сказал(а):↑сам придумал что-то, сам подловил
во-первых, где пример того, что лучше использовать Set, тут уже идет привязка к генерации hashcode к конкретной jvm.
во-вторых, если ты не переопределишь hashcode, его jvm сгенерирует автоматически, что тоже зависит от имплементации jvm
Нажмите, чтобы раскрыть...Потому что ты видимо где-то услышал что List>Set в хибернейте, вот статья где тебе это обьяснят почему это не так и что List>Set был из-за каких-то старых багов в фреймворке.
какая разница какой jvm, если он будет использоваться один и тот же во всех инстансах на проде?)
tDmn/// сказал(а):↑Вкратце, ты не умеешь читать. Надеюсь, никогда не встречусь с твоим кодом.
Нажмите, чтобы раскрыть...ты то умеешь читать)
- hashcode можно поставить constant числом для хэшмапы
- КОКОКО id.equals(id2), где id, id2 = null будут равны, нужно сравнивать по другим полям КОКОКО
Aragorn_ сказал(а):↑как создать хэшкод, когда id еще не создан хибером и при этом больше никаких полей нельзя юзать?Нажмите, чтобы раскрыть...tDmn/// сказал(а):↑Хэшкод (и сам метод equals) нужен для проверки эквивалентности объекта. Если твоя проверка эквивалентности проверяет непосредственно id - тебе не кажется, что это какая то некорректная проверка? А если именно id является твоим качественным параметром эквивалентности - в чем твоя проблема? Все объекты с id=null (или 0, хз, что там за поле) будут считаться эквивалентными.
Нажмите, чтобы раскрыть...
Aragorn_ сказал(а):↑- hashcode можно поставить constant числом для хэшмапы
- КОКОКО id.equals(id2), где id, id2 = null будут равны, нужно сравнивать по другим полям КОКОКО
Нажмите, чтобы раскрыть...У тебя явные проблемы с понятием эквивалентности. Больше тебе отвечать не буду, можешь не утруждаться.
Aragorn_ сказал(а):↑Потому что ты видимо где-то услышал что List>Set в хибернейте, вот статья где тебе это обьяснят почему это не так и что List>Set был из-за каких-то старых багов в фреймворке.
какая разница какой jvm, если он будет использоваться один и тот же во всех инстансах на проде?)
Нажмите, чтобы раскрыть...
большая, твой код могут потом запустить на другой версии jvm, это вполне резонная проблема, например после log4j бага, многие обновляют jvm/jre/jdk
ну в принципе от задачи зависит, по дефолту я лист юзаю, все равно hibernate через призму collection смотрит, наверное.
p.s. одна из причин, не надо hashcode переопределять
AMDkrolyan сказал(а):↑большая, твой код могут потом запустить на другой версии jvm, это вполне резонная проблема, например после log4j бага, многие обновляют jvm/jre/jdk
Нажмите, чтобы раскрыть...что-то суровое, я не в курсе
AMDkrolyan сказал(а):↑ну в принципе от задачи зависит, по дефолту я лист юзаю, все равно hibernate через призму collections смотрит, наверное.
Нажмите, чтобы раскрыть...По дефолту юзать лист это как по дефолту юзать Object, а ху** не так сказать)
Aragorn_ сказал(а):↑По дефолту юзать лист это как по дефолту юзать Object, а ху** не так сказать)
Нажмите, чтобы раскрыть...
ну в чем профит сета, просто так ? если юзаешь его, надо определить hashcode + equals для entity, а это лишний код, имхо
насчет генерации hash по дефолту, там обычно адрес памяти берется, но опять же, такие вещи редко когда нужны, только вот если не какой-то специфический jvm, вообще тяжело найти кто бы юзал default hashcode, надеясь на jvm
AMDkrolyan сказал(а):↑
ну в чем профит сета, просто так ? если юзаешь его, надо определить hashcode + equals для entity, а это лишний код, имхо
насчет генерации hash по дефолту, там обычно адрес памяти берется, но опять же, такие вещи редко когда нужны, только вот если не какой-то специфический jvm, вообще тяжело найти кто бы юзал default hashcode, надеясь на jvm
Нажмите, чтобы раскрыть...в плане лишний? 90% бизнес логики в базе хранить уникальные данные, зачем повторяющиеся? Это как сказать "зачем создавать index в базе, ведь можно просто следить, чтобы уникальные записи писались".
Конечно, если кейс, например логи хранить в базе(или подобные данные не критической важности), где ты батчами из базы хочешь читать и записывать их, тебе наплевать что там будет повторяться 10 раз одно и тоже, указываешь там batchSize и гоняешь туда списками их, то тогда проще, но разве это частый кейс?
Куда чаще идет бизнес логика где важно, чтобы твои сервисы и базы были легко заменяемы, чтобы например если кто-то не настроил нормально базу - не нарушил контракты системы и так далее.
В бизнес логике ты куда чаще работаешь одновременно с не большим количеством записей из базы за одну итерацию. И куда важнее гарантия качества, а не какой-то надуманный микроперформанс, который никогда не будет заметен в масштабах джава систем. В общем это не то место, где нужно говорить "нуу, list быстрее чем set", это какие-то кейсы уровня с++ программ.
Aragorn_ сказал(а):↑в плане лишний? 90% бизнес логики в базе хранить уникальные данные, зачем повторяющиеся? Это как сказать "зачем создавать index в базе, ведь можно просто следить, чтобы уникальные записи писались".
Конечно, если кейс, например логи хранить в базе(или подобные данные не критической важности), где ты батчами из базы хочешь читать и записывать их, тебе наплевать что там будет повторяться 10 раз одно и тоже, указываешь там batchSize и гоняешь туда списками их, то тогда проще, но разве это частый кейс?
Куда чаще идет бизнес логика где важно, чтобы твои сервисы и базы были легко заменяемы, чтобы например если кто-то не настроил нормально базу - не нарушил контракты системы и так далее.
В бизнес логике ты куда чаще работаешь одновременно с не большим количеством записей из базы за одну итерацию. И куда важнее гарантия качества, а не какой-то надуманный микроперформанс, который никогда не будет заметен в масштабах джава систем. В общем это не то место, где нужно говорить "нуу, list быстрее чем set", это какие-то кейсы уровня с++ программ.
Нажмите, чтобы раскрыть...я ничего не понял
причем здесь уникальность
ты прост добавил строчку в коллекцию и сохранил ее, ну можешь юзать сет как аналог фильтру, но честно говоря также можно проверить, что данные не повторились случайно, такой вариант более логичный и удобный
типо на уровне бизнес логи ты подготовил данные, что надо сохранить, а потом передаешь это на repository слой
а так ты обременяешь репо слой, тем что ему еще надо хешкод ентити вычитывать и т.д.
Тема закрыта
-
ЗаголовокОтветов ПросмотровПоследнее сообщение
-
mirrorobjects 27 Apr 2024 в 05:17Сообщений: 2 27 Apr 2024 в 05:17
Сообщений:2
Просмотров:3
-
Сообщений:1
Просмотров:0
-
me11 27 Apr 2024 в 04:00Сообщений: 10 27 Apr 2024 в 04:00
Сообщений:10
Просмотров:12
-
Сообщений:5
Просмотров:8
-
Сообщений:6
Просмотров:8