Это копия, сохраненная 30 марта в 15:02.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Можешь локально поднять постгрес, но нахуя тебе оно?
Или https://github.com/yandex-qatools/postgresql-embedded
>чтоб data jpa протестить с postgresql нужно тестконтейнер создавать
Необязательно, хошь h2 юзать, взяв на себя риски впороться в разницу диалектов - валяй, никто тебя не осудит.
Но тестконтейнерс на самом деле мегапиздат, так что ты подумай, от чего отказываешься.
Ваши критерии по хард-скилам для мидла джависта?
Умение написать аналог джавы за 10 часов, военный опыт в дешифровке энигмы, понимание отчётов об ошибке градла.
return num;
return 0;
Или
return num > 0 ? num : 0;
Однажды его применил там где он вообще нахуй был не нужен. Очень был собой доволен и потом на собесах выёбывался этим паттерном. Сейм+соглы?
Objects.requireNonNullElseGet(Optional.of(num).filter(n -> n > 0).orElseGet(() -> null), () -> 0);
Как вы учили Spring?
Скачал три курса, во всех трёх всё по разному делают и в разном порядке. Только основы одинаковые пока что.
Взял и выучил, вообще без проблем.
Поч?
Побитовая хуйня какая-нибудь наверное
Главный скил - умение самостоятельной разобраться в любой ебале. И это не столько про чтение гайдов как реализовать фичу, сколько про траблшутинг как по рандомному стектрейсу понять какого хуя не работает и как починить.
switch (num) {
case 0 -> урожай 0;
case _ if num > 0 -> num;
case _ -> throw new PizdabolException("")
}
До Spring осталось two months давайте поднажмём подписчики
А причем тут жеба?
нет бро
Нет, полтора месяца учу, нерешаемых проблем не вижу, кроме проблем со сном.
Боже, меня уже на таймер ставят... Ну честно сказать про минет я пошутил. Думаю и без работы ротиком смогу добиться~
Дошёл. В практических примерах ещё нет, но читать читал, относительно понятно.
Сложно снабженцем работать зная, что от любых твоих действий зависит вся контора, ты царь и бог работяг на производстве и монтажников в поле и по одному твоему слову они поедут домой сосать хуи или останутся работать зарабатывая сотни и получать за это 40к в качестве насмешки.
>относительно понятно.
Эффект Даннинга Крюгера? Ну так не интересно. Не вводи в заблуждение, кстати других, мол просто все хуе мое. Ты просто пороха-то не нюхал и не шаришь.
>Смотрел от отуса,
О, от OTUS у меня есть курс.
>+ книги обязательно не одну.
А какие? Я знаю только Спринг быстро и Спринг в действии
>их не надо делать, просто делай акцент на java коде.
А это как? Типа сосредотачиваться над тем, что все эти вещи делают, а не над связью их в приложуху?
>псевдопсихология для разводки гоев на шекели.
Тебе виднее. А так я бы С++ с нуля учить бы не стал, вот где реально ад и израиль.
https://2ch.hk/pr/res/2973076.html (М)
Розжиг со стороны конкурирующих платформ прошу репортить
И как это прокачать? Вообще иногда хуй знает что стектрейсы значат. Чисто гугл-стековерфлоу-первый ответ. И 70% проблем решаются без понимания сути проблемы. В остальных 30% случаев вообще рандомно.
Но причем тут это? Я скорее про то что надо по знанию стека на собесе ответить, чтобы в большинство крупных компаний мидлом залететь.
Ну новая минорная версия бута вышла, че такого то?
Опять небось повыкидывали кучу классов, которые задепрекейтили месяц назад, поэтому нихуя не заведется.
Из языков программирования знаю только Питон, но Джава выглядит интересно, особенно в контексте ООП. Что почитать, чтобы шарить за основы и десктопную разработку на Джаве?
А что за приложение, подскажите пожалуйста.
Очень плохо с мыслительными процессами, как бугдто в голову дым напустили.
LibGDX самый лучший для desktop/android.
Пирацетам или какой-нибудь родственный (ноопепт, фенил-пирацетам), л-карнитин (от витамира в аптеках был с формой которая лучше усваиваться должна)
Есть ли спираченный курс где-то?
https://www.udemy.com/course/java-development-for-beginners-learnit/
Думаю купить, но при наличии торрента с удовольствием воспользуюсь этой опцией.
Да вы заебали со своими говнокурсами приходить. Сдохните, пожалуйста. Или в шарп свалите. Говно блять жрут, а потом приходят и доказывают, какие же они бля знатоки неебаца
Лучше скажи когда котлин полностью сдохнет
Заткнись лох
Даю тебе второй шанс.
Соус
Мечта. Я бы всё отдал чтобы вылизывать азиаткам ноги в колготках.
Durak
PaymentGatewayOperationHandleAbstractBeanFactory
Аргументация:
1) Сервисы могут отправлять друг другу обновления информации, если это необходимо. В конце концов можно сделать глобальное оповещение если нужно.
2) Использование локальной базы данных позволяет добиваться сверхскоростной работы приложения, держа в оперативной памяти всю/кеш бд, и вместо 100 мс времени доступа до удалённой бд иметь 0,1 нс времени доступа до поля у объекта.
У тебя таким образом просто велосипедная самописная отзеркаленная база данных получается.
Это у тебя будет работать, пока вдруг не сломается какая-то маленькая штука, и тогда это всё целиком наебнётся, потому что никакой resilience у тебя не заложено.
Я не могу тебе особо дать примеров не зная, как ты конкретно реализовывать собираешься.
Ну, например, наебнётся у тебя в один прекрасный момент десериализация из-за бага в библиотеке. Данные сразу станут рассогласованными, и в зависимости от логики это может сильно разрастись и протечь в основную базу source of truth, попортив данные в ней.
Принцип PAELGOVNA.
Ты не прав, потому что родился. А теорему мог бы и открыть хотя б.
Таким образом ты теряешь гарантии. Далеко не всегда(практически никогда) потеря гарантий стоит того.
Хм, хотя нет, только в личных проектах, а в том что я наконтрибьютил в попенсорс нет. Интересно.
>В чём я не прав?
Во всем прав.
Просто васяны настолько преисполнились и привыкли к трехзвенному монолиту, что сама идея побить модель данных на несколько частей, пожертвовав при этом кое какими гарантиями консистентности, для них звучит настолько неприемлемо и кощунственно, что они со старта уходят в манямирок, и городят тормозной, глючный и совсем не масштабирующийся распределенный монолит, называя оный "микросервисной архитектурой".
>то есть всё кроме склайт
Блять, вот эту часть тезиса пропустил. Тогда не, не прав, поел пуд говна.
Как ты вообще себе это представляешь, на конкретном примере, даже если бы было возможно? Т.е. по умолчанию ты вызываешь условный геттер, который уже на этапе компиляции существует. А даже если в рантайме в уже загруженный класс добавить новый геттер (что невозможно технически), тебе все равно придется его вызывать через reflection и т.п., что хуже чем получить с хешмапы.
Не выдумывай.
То что ты описываешь, по семантике схоже с понятием скоупа в DI контейнерах: типа, вот ты выполняешь юзерский реквест. К этому реквесту биндится юзер и вся его подноготная по мере того, как ты ее извлекаешь, и этот инстанс юзера условно существует до тех пор пока реквест не обработан - вуаля, реквест-скоуп.
Но с другой стороны, ты щас какой то ебаный гемор описываешь. Докидывать, параметры... Нахера так сложно? К тому же - ты вот пишешь "каждый класс мог бы докидывать свои параметры и их же использовать" - а что по твоему должно случиться, если класс, который использует параметры твоего юзера, решил поиспользовать их раньше, чем тот кто их докидывает, их по факту докинет?
Ну надо тебе, изъебнись теми средствами которые тебе уже даны:
1. Заведи реквест-скоуп бин юзера
2. Нутря этого юзера либо заебень ленивоинициализируемыми - типа кто первый раз погеттил свойство, тот его и посчитал. Либо - открой сеттерами: кому надо тот их проинициализирует.
Хуй знат насколько оно практично, как по мне - бред сивой кобылы, но под твою постановку задачи как будто подходит, и работать в теории будет.
Слив принят.
Ну например при запуске приложения компилируется User со всеми запрошенными на момент запуска полями.
А в чём не прав?
Я не про удобство кода сейчас говорю, а про оптимизацию, а DI к оптимизации мало отношения имеет. Если несколько модулей приложения общаются друг с другом внутри одной jvm, передавая строку с айди/объект uuid, приходится к данным этого пользователя получать доступ через Map<String, ModuleLocalFoo>. Но если бы не было никаких библиотек, никакого внешнего кода, то можно было бы завести класс User, где была бы тысяча полей, каждое поле вместо одной Map<String, ModuleLocalFoo>, передавать этот самый User и оптизировать доступ к данным в 6-12 раз (провёл бенчмарки, в 6 раз если сравнивать volatile и ConcurrentHashMap, 12 раз если сравнивать простое поле и HashMap).
Да, частенько.
public List<User> getUsersByAge(int age) {
List<User> usersByAge = ...
return usersByAge;
}
или
public List<User> getUsersByAge(final int age) {
final List<User> usersByAge = ...
return usersByAge;
}
А ты вот прежде чем в туалет сходить тредик на двачике не создаешь? Типа ну ебать, тут анонов-то никак не разобраться.
нет единого стандарта
придешь на одно место работы и там будет первый варик, сменишь его на другое и там уже будет второй
Просто ответь себе на вопрос, что делает final перед параметром метода, и сразу определишься.
Корректно не пытаться бездумно подражать т.н. хорошим практикам и думать своей головой, что и зачем нужно.
Хехе. Чел с фантазией - далеко пойдешь.
Возьми для примера парочку эксепшонов и ответь для себя на вопрос - что должна делать программа, если срать запрещено?
NullPointerException запрещен. Ты складываешь Integer'ы. Два + null = что?
IOException запрещен. С чем будет работать код, читающий файлик, которого не существует?
OutOfMemoryError запрещен. Память кончилась, аллоцировать некуда. Что в твоей парадигме будет означать "вычислять хуйню до победного" для данного случая?
>Два + null = что?
segfault
>С чем будет работать код, читающий файлик, которого не существует?
>Память кончилась, аллоцировать некуда.
kill от ос
Мима
>Меня всегда интересовало, что будет, если выпилить под ноль все эксепшены
>Программа не сможет крашнуться, потому что краш это тоже эксепшен
А можно я кину Error?
программа
>Как быстро это произойдёт?
Очень быстро произойдет segfault. В джаве NPE тоже через перехват segfault работает, но в джаве есть четкая логика что в этом случае делать. А если NPE не выбрасывать у тебя быстро закораптится память, включая внутренние данные JVM.
Так сегфольт это тоже эксепшен. Не джавовский правда.
Нельзя. Яскозал.
Про какую конкретно ты роадмапу? И почему кому-то должно быть не похуй?
Кстааати, торадиционный вопрос. Как у тебя дела обстоят с многопточкой? Шаришь за hb/sw/po? Можешь понять тонкую разиницу между opaque и plain семантикой? А за rc пояснишь?
Ну как уже сказали - крашится все прекрасно будет, потому что внутренности джавы кидаются эксепшенами, просто они будут очень непонятными
960x720, 0:02
Блять ну спроси у того, кто составлял этот роадмап. Чё ты у нас, у левых людей спрашиваешь. Давай я к тебе приду на новый год и спрошу - Васян, а почему в рецепте селедки под шубой яблоко? Или а почему мартини пьют с огурцом? Он просто так чувствовал ебать! Это просто полёт фантазии какого-то чела из интернета. Всё.
> внутренности джавы кидаются эксепшенами
Ну так а в условии что? Полное выпиливание эксепшенов.
Эта штука исключительно ради заебов команды/линтера, практического применения я у нее не видел, делай как удобнее, но обычно файнал параметры не делают
Из внутренностей джавы? Ты же написал что "написано", предполагается в исходном коде твоей программы.
Если ты входишь из внутренностей джавы - то это и не 🍊 вообще, там понятия исключений нет. В ОС есть сигналы как segfault, kill, а в процессоре - прерывания.
Если программа не может крашнутся, то у ❄️ например есть интересный термин, описывающий это - Undefined Behaviour (UB), то есть программа может сделать все что угодно - можно Новогодний Выпусколжать работать не так как ожидалось, может остановится и т.д.
>Шаришь за hb/sw/po? Можешь понять тонкую разиницу между opaque и plain семантикой? А за rc пояснишь?
А как вы это используете в повседневной работе?
> есть интересный термин, описывающий это - Undefined Behaviour (UB),
Вот уж пролил свет так пролил. Спасибо, без тебя бы не догадался!
Я в самом начале говорил, что интересно, как будет выглядеть Undefined Behaviour.
Могут появиться, могут и не появится. Тебе словарь нужен посмотреть слово "недетерминированный"?
К кунчикам подкатываю. А так, можно оптимизировать алгоритмы же.
Так че по вопросу? Шаришь или впервые слышишь?
>А так, можно оптимизировать алгоритмы же.
Конечно можно. Только вот вопрос как вот конкретно ты их используешь на вашей кодовой базе в твоей Застолье, каждый раз/день/месяц когда приходишь на работу и садишься за стол. Можешь примеры алгоритмов, которые ты уже оптимизировал в вашей Новогодний Выпускуктовой кодовой базе?
Я не понимаю чего ты хочешь добиться собственно говоря.. Типа обесценить, мол нинада и нужна? Ну мне надо, тем более для того, что я хочу сделать в будущем. Такие дела.
>Я не понимаю чего ты хочешь добиться собственно говоря.. Типа обесценить, мол нинада и нужна?
Так вот я и пытаюсь понять где ннада и нужна. Особенно новые семантики памяти, выглядит как очень специфичный инструмент, вот мне и интересны конкретные примеры как ими можно улучшить реально применяемые алгоритмы?
Ну вот, например акью/релиз. У него по сравнению с волайтайлом нет распространения на остальные переменные, so т.е. Из-за этого преколы всякие могут возникать. Опакью вот хызы, если честно. Вроди ее как флаг можно ебнуть, ну тип прерывания/отмены.
Ну вот получил я список ConstraintViolation, что мне с ним дальше делать? Есть стандартные подходы?
Ну ты же понимаешь, что не будет хуёв, так как им просто неоткуда взяться. Поведение будет всё ещё определено, но не полностью.
Срать хуйнёй начал ты, решив поумничать, высрав ответ ради ответа, без какого-либо смысла.
Я понимаю что что-то есть и что -то можно. Я говорил про конкретные оптимизации реально применяемых алгоритмов
Я вообще не в курсе о чем ты говоришь, валидация - это просто принцип, он может реализовываться разными способами. Ты наверное какую-то либу используешь
Не, слушай, ты душный нахуй. Я б тебя уволил.
>про конкретные оптимизации реально применяемых алгоритмов
На скрине блять что? Не реальный алгоритм и не применямый? Ты долбоеб? Или слепошарый, к окулисту сходи, уебан.
А еще учитывая, что ты на мои вопросы так и не ответил - пошел нахуй. И не возвращайся.
>Я б тебя уволил.
А ты в каких Рогах и Копытах работаешь, уважаемый? Просто чтобы знать размах гения.
>На скрине блять что? Не реальный алгоритм и не применямый? Ты долбоеб?
Алгоритм присвоения значения переменной? У тебя именно он подсвечен. Не ну тут охуеть конечно, признаю, не заметил. Можешь гуглу продавать идею.
Я конкретно про Jakarta Validation.
Наоборот очень приятно. Куча удобных функций, всё под рукой, не нужно писать никакие StringUtils. Я писал синхронный код на gRPC и на котлине это просто сказка, а в джаве боль и страдания с фьючерсами.
Щас бы в 2к23 нахваливать петухлин, единственное отгичие которого от джавы в дегенеративности синтаксиса.
>Абсолютно разные вещи
Ну ты разницу-то назови. Тем более обе они работают на одних и тех же гарантиях в отличии от кафки и постгресса.
Красивых.
Корутины это же реализация многопоточности,а не ассинхронности,разве нет?
Не ворочайся, слитое.
Они почти всегда вместе ходят кроме джaвaскpипта, где один поток и виртуальные треды по очереди запускаются.
сам жс однопоточный, но рантайм нет
АХАХАХАХ ТУПОЕ ЕБЛО
Лаунчер свой пишешь что-ли? Можешь посмотреть в исходниках других лаунчеров, как они это делают, например у llaun.ch.
Те не похуй? Завтра новый год, а ты о хуйне какой-то думаешь. Надо думать о предстоящей тусе!
Это как-то противоречит?
Math.max(num, 0)
Таненбаума почекай
Сейчас приходится отдельно нажимать "запустить градл таск", потом подождать пока оно все там у себя сделает и напишет, что слушает, потом отдельно нажать ремоут дебаггинг, и то через раз цепляется.
Жыдовская подстилка порвалась
>Корутины это же реализация многопоточности,а не ассинхронности,разве нет?
Да, но в корутинах как и в виртуальных тредах основная фишка в том, что блокирующие операции заменяются на асинхронные. Что позволяет обходится малым числом нативных потоков.
Синхронные операции не заменяются на ассинхронные,просто блокировка виртуального потока не блокирует нативный и он может продолжать вычисления
Именно, что заменяются. Поэтому для корутин нужен неблокирующий апи. В виртуальные треды делают это под капотом.
Потому что в пользовательском режиме нельзя нормально спать, только ядро может отдыхать как положено, без бази вейта джоин будет длиться время равное времени переключения планировщика
Видимо это слишком грубое вмешательство в жизнь планировщика. Не могу точнее ответить, но как-то читал на эту тему, кароче поспать с хорошей точностью сложно в конвенциальной оперционной системе.
Как будто выбора дохуя - либо жидея, либо вскод.
Можешь еще некро иде вспомнить типа нетбинса и эклипса, но на них наверное даже индусы уже не пишут.
А нахуя спать с точностью-то? Просто сказать планировщику поставить поток в пул ждущих окончания, прибить его айди к ожидаемому треду и после окончания всех тредов вычитывать, кто ждёт конца и запускать.
Ноне джава в виндовсе только привязана к планировщику в операционке, в линуксе она от него отвязана. И то в джаве 10 приоритетов в винде 7.
Он не выглядит как говно хотя бы, плагинов полно.
Не знаю насколько он удобен - я все таки бесплатной идеей ультимейт пользуюсь, как и все в моей тиме.
Кто не даёт?
https://man7.org/linux/man-pages/man2/futex.2.html
Лочишься и ждёшь сколько надо. Собственно джава по крайней мере раньше активно использовала футексы для управления и синхронизации тредами.
Я просто нагуглил ключ - поэтому для меня бесплатно. Кто то кряки использует и для них тоже она бесплатна.
Мало того что она стоит дохуя, так я еще и ебаться с оплатой должен? Не хотят моих денег - значит бесплатная.
Ну он сказал что не даёт.
>наверное
Пукнуть в лужу любой может, да.
>эклипса
Я в нём пишу. Spring Tool Suite вполне годная среда.
И я не индус, я белый, этнический русский.
У меня есть ручка эндпоинт, который по списку id юзеров возвращает юзеров. Если список пустой - то и вернется пустой список. А что надо передавать(получать), чтоб возвращать всех пользователей?
Пробовал вариант с пустым списком/нулом - но эта хуйня не работает с формдатой и фронтом - для жс похоже нет разницы между null и пустой строкой.
>что надо передавать, чтоб возвращать всех пользователей?
Очевидно что твои апи сделаны через Тулуп. Вот пример более-менее адекватного решения: https://developers.onelogin.com/api-docs/2/users/list-users
У них
GET /api/2/users - получить всех пользователей
При этом у них есть query параметр user_ids, то есть можно сделать
GET /api/2/users?user_ids=21,63,12,84
У получить отдельных юзеров если надо. Ты видимо делаешь POST, но это опять же хуёвый дизайн.
>>GET /api/2/users - получить всех пользователей
>>GET /api/2/users?user_ids=21,63,12,84
Ок, а какой запрос надо отправить чтоб получить в ответ пустой список?
Вопрос как бы в том как сделать тройную логику - все/никто/по списку. Я не понимаю как такой вопрос гуглить и как узнать что в таких случаях обычно делают.
Пример максимально упростил, на деле там приходят данные с 5 списками и десятком других полей, поэтому дробить это на разные эндпоинты не вариант.
Веселье началось когда понадобилось загружать еще и список файлов. Я смог это сделать через @RequestPart - в постмане все ок, но кривой свагер не умеет октет-стрим назвать жсономи получаем 415 в ебало. (а значит тестеры не смогут потестить и вернут на доработку)
А вариант через @ModelAttribute не умеет в массивы и ему что нул, что пустой список похую. Передавать просто строку, чтоб руками ее в жсон переделывать тоже не очень хочу, но пока это видится как единственный рабочий вариант.
>>там приходят данные с 5 списками
Ну то есть если список - null, то его игнорим, если пустой - применяем ко всем (юзерам, группам и тп), если какие то конкретные значения - то используем их.
Бля да не должно быть никаких пустых списков. Это опять хуёвый дизайн. Если у тебя нет данных по запросу - просто верни код 404. А на фронтэнде проверят. Какой блять может быть null? Ты на фронтэнде пишешь try { const response = await axios.get('/api/users'); } catch(e) { if (e.response.status === 404) { тут ты обрабатываешь пустой список пользователей } } Всё! Так ясно и понятно. Тебя выкидывает в catch и в катче ты уже работаешь с ошибкой!
Как у тебя ручка выглядит?
GET api/2/nihuya
Тут возникает вопрос: как различать ситуацию когда по заданным критериям ничего не найдено и когда отправили запрос на неверный URL?
В целом коды http - говно, они не для приклвдного API задумывались.
filter|query={...json or some expression}
Но это такое себе, лучше уж сразу graphql прикрути.
>ничего не найдено и когда отправили запрос на неверный URL?
Это ничо принципиально не меняет. Что так ты данные не получишь, что сяк. Если тебе прям ТАК ВАЖНО отличать сорта говна, можешь отправлять типа такого ответа
HTTP/1.1 404 Not Found
{
"message":"API Endpoint does not exist",
"type": ENDPOINT_DOES_NOT_EXIST
}
Или
HTTP/1.1 404 Not Found
{
"message":"Requested resource not found",
"type": RESOURCE_NOT_FOUND
}
Ну и там уже в катче проверять тип.
У меня таких ситуаций в принципе не возникает. Ну типа, как вообще можно ошибиться в написании URL? Это же элементарно детектиться.
>HTTP/1.1 403 Forbidden
>Your current balance is 30, but that costs 50.
Как перестать орать.
>>2989561
Еще один ахуительный пример! С одним и тем же кодом идет ошибка и нормальный ответ. Во первых непонятно как должна на такую хуету реагировать инфраструктура: кеширование, балансировщик, мониторинг. Во вторых на клиенте все равно придется всегда, независимо от HTTP парсить респонз чтобы понять что там на самом деле.
В нормальных RPC протоколах, HTTP коды используются только для транспортных ошибок. Ошибки сервиса идут с HTTP 200. А REST непродуманное говно, которое склепали на коленке и которое хреново работает в сложных системах.
У меня джун-сеньор тоже доказывал, что комментарии не нужны и так всё понятно из кода. Сразу видно что человек ни одного костыля в своей жизни не писал где бы приходилось бы во всех подробностях объяснять мотивацию почему так, а не иначе. А если ни одного костыля за жизнь разработчик не написал, то это много говорит про его опыт работы.
>>HTTP/1.1 403 Forbidden
>>Your current balance is 30, but that costs 50.
>Как перестать орать.
Попробуй рот закрыть.
>Еще один ахуительный пример! С одним и тем же кодом идет ошибка и нормальный ответ.
Сказал двухсоточник.
>Во первых непонятно как должна на такую хуету реагировать инфраструктура: кеширование, балансировщик, мониторинг.
Какое ещё кеширование? Ща, закешируем ответ для высокопривелегированного юзера и всем отдадим. При чём тут балансировщик? И зачем тебе мониторить 404 на апи сайте?
> Во вторых на клиенте все равно придется всегда, независимо от HTTP парсить респонз чтобы понять что там на самом деле.
Нет, не всегда. Более того, в большинстве случаев код однозначно определяет вид проблемы.
Твой пример про 404 это херня, потому что если у тебя во фронте неправильный url закоден, то это баг, и его надо фиксить, а не обрабатывать.
>В нормальных RPC протоколах, HTTP коды используются только для транспортных ошибок. Ошибки сервиса идут с HTTP 200. А REST непродуманное говно, которое склепали на коленке и которое хреново работает в сложных системах.
В каких нормальных? Только не говори GraphQL -- это ебанутое переусложнённое говнище с дырами.
У вас (веб-макак) разве не должно быть стандарта как это делать правильно? Зачем изобретать велосипеды когда всё сделано за вас?
Так те кто против как раз о том что надо писать комменты к костылям и объяснять ЗАЧЕМ это написано, а не тупо пересказывать ЧТО код делает, как это часто в джавадоках делают.
Как будто я из сигнатуры не вижу что там за @param и @return
>117,000+ req/se
>101 millisecond startup
>57 MB modular run-time image
У м-меня сервис на р-ряботе 117req/day... 👉👈
Я и не понимаю чего другой анон упрямится. Вот же стандарт делай по нему и все тебе скажут спасибо. Нет же, надо что-то своё изобретать и всех путать.
>>2990194
Потому что джавадок это не "комментарии", это документация. Всех похер, что там у тебя на самом деле реализовано, заказчик придет и тыкнет пальцем в документацию и скажет должно быть так как написано здесь.
>Какое ещё кеширование? Ща, закешируем ответ для высокопривелегированного юзера и всем отдадим. При чём тут балансировщик? И зачем тебе мониторить 404 на апи сайте?
Так бы сразу и сказал, что ты вротэндер. Только хули ты полез бек обсуждать непонятно.
>Твой пример про 404 это херня, потому что если у тебя во фронте неправильный url закоден, то это баг, и его надо фиксить, а не обрабатывать.
Объясняю для тупых вротэндеров: на фронте ты нихуя не помониторишь, поэтому ошибки надо логать на беке и смотреть сколько их. Если идет резкий рост 404 значит вротендеры где-то налажали и надо смотреть логи, куда эти дебилы лезут. А если ты будешь 404 использовать для прикладного уровня, то тебе надо делать специальный мониторинг который будет различать прикладной уровень и сетевой.
>В каких нормальных?
Да в древнем SOAP люди уже это понимали.
> значит вротендеры наложили
Ни разу мой фронт не наложал, а бэкенд всё время ломает обратную совместимость и древние клиенты долбятся в несуществующие URL. На вопрос какого хуя на бэке отвечают, что "ню, ми жи ни думали шта кто-та эта пользоваться". Каждый раз в ахуе насколько им похуй что они говно, а не API делают.
>>Какое ещё кеширование? Ща, закешируем ответ для высокопривелегированного юзера и всем отдадим. При чём тут балансировщик? И зачем тебе мониторить 404 на апи сайте?
>Так бы сразу и сказал, что ты вротэндер. Только хули ты полез бек обсуждать непонятно.
Ты бы лучше сам сказал, что ты админ, а не девелопер.
>>Твой пример про 404 это херня, потому что если у тебя во фронте неправильный url закоден, то это баг, и его надо фиксить, а не обрабатывать.
>Если идет резкий рост 404 значит вротендеры где-то налажали и надо смотреть логи, куда эти дебилы лезут.
На проде? Пройдя через qa и автотесты?
Если у тебя такое может пролезть на прод, то у тебя вообще туда может попасть любое говнище, которое ты никакими мониторингами не отловишь, потому что оно чисто на фронтенде будет.
Ты описываешь очень специфическую проблему и предлагаешь под неё архитектуру переделывать. Это нонсенс, она решается гораздо проще.
>>В каких нормальных?
>Да в древнем SOAP люди уже это понимали.
Соап мог мог работать поверх разных протоколов, естественно он должен был абстрагироваться от деталей HTTP. И сдох он как раз, потому что был слишком замудрёный, и потому что нет никакого смысла делать мультипротокольный протокол (простите), везде есть HTTP.
А в HTTP уже сразу было дохера кодов, которые должны были возвращаться логикой, и которые никогда бы не вернул веб-сервер типа payment required.
Возможно если бы сейчас проектировали http, его бы сделали по-другому, потоньше и попроще, может разбили бы на два, но вот такой он уже существует и непонятно, почему нельзя использовать его имеющиеся фичи на полную. А то ведь можно просто tcp-пакеты гонять, там никаких состояний нет.
Были бенчмарки что джава 7 лямов реквестов в секунду выдаёт.
/tick sprint в майнкрафте сделал. Оптимизированное ядро на последней версии игры с оптимизированными флагами выдаёт 678 тиков в секунду, а всё то же самое, но на грааль вм уже 805 тиков в секунду. Нативную компиляцию для майна я не знаю, как врубить, там же плагины, которые в виде .jar распространяются.
В том, что тратишь много времени. Есть оптимальное соотношение затраты на тестирование/количество не найденных багов. Написание теста на сценарий использования API даёт минимальные затраты на максимальным количеством найденных багов. Написание юнит тестов на все сценарии использования каждого метода даёт максимальные затраты на минимальное количество найденных багов.
Это история про то, что дверь будут открывать внутрь в 95 % и это нужно протестировать. В оставшихся 5 % её будут дергать обратно, бить в неё ногой, вставлять отвёртку в замочную скважину (при том, что она открыта) и так далее. Нужно покрыть в первую очередь сценарий который будут использовать 95 % времени, а то что будет использовать 5 % времени тестировать по остаточному принципу.
Я в 5 % вообще всё засунул в мысли выше. 0,1 % на пикник ногой. 0,2 % на попытку снять с петель. 0,25 % на то что повиснут на ручке и так далее.
Это то что называется в теории API "незадокументированным использованием API". Если пользователь системы вместо того чтобы использовать её как написано в документации пытается её сломать или просто игнорирует документацию и использует API интуитивно, то нет ничего удивительного, что он на каком-то моменте сломается.
Нужно ли "защищать" API от подобного тестами? Да нужно, если есть ресурсы. Если ресурсов нет (а их всегда нет если мы говорим про коммерческую историю), то тестов покрывающих 95 % пользовательских сценарий и 100 % задокументированных (предполагаемых как нормальные) сценариев использования вполне достаточно.
Незадокументированные случаи могут положить сервер, и тогда придётся избавляться от бага, хуй положить не получится. Это называется уязвимость. К тому же покрытие 100% даже задокументированных случаев вполне может вылиться и в 5 и в 50 строчек тестов на строку кода, в зависимости от случая.
> это называется уязвимость
Верно, про защиту ПО я не думал в этом контексте.
> покрыть 100 % задокументированных случаев большая работа
Задокументированый не с точки зрения, что мы его когда-то встретили, а буквально: тот способ работы с API, который описан в публичной документации. У нас в API это буквально два сценария.
Ну так если незадокументированный случай работы != попытка сломать, а просто какой-то редкий случай, то он должен работать, потому что в любом случае придётся фиксить обнаруженный баг, а фиксить баг после нахождения его тестами гораздо легче, чем расследовать с самого верха, придя к конкретному методу часов через 6.
Да, но есть разница между тем "случилось, надо исправить" и "не случилось, но мы переносим сдачу проекта на месяц, чтобы вероятней не случалось". По крайней мере на моей работе первый вариант предпочтимее чем второй.
Между сдать забагованное говно и потерей клиента выбирают всегда первый вариант.
Это выглядит примерно так: нам нужна фичанейм в вашем продукте в следующем релизе иначе мы начнем рассматривать альтернативного провайдера. Менеджеры стоят на ушах и спрашивают у нас можем ли мы выкатить фичу к следующему релизу. Мы говорим какие-то сроки, которые игнорируются и нам говорят "ребята кровь из носу через 3 недели у нас должен быть релиз с фичейнейм". Ну и что смог за 3 недели сделать, то и сдаешь заказчику.
Вариантов где можно сесть и попердывая год пилить какую-то фичу нет. Даже API для нового продукта у которого нет ещё клиентов писался через пень колоду потому что "нам надо, чтобы у концу года было 5 клиентов подписавших контракт на год". Менеджеры смотрят сколько времени ушло у предыдущего продукта, чтобы получить 5 клиентов и говорят, что продукт должен быть готов за 2 месяца иначе 5 клиентов мы хуй получим.
Ну тут уже проблема менеджеров, которые принуждают программистов участвовать в скаме. Если уж и рассуждать о эффективности методики превентивного заливания тестами, то стоит рассматривать время, потраченное для создания одного и того же продукта.
Это нужны эксперименты. Может где-то на просторах Интернета можно найти. Я помню цифры про +30 % ко времени проекта если делать через TDD по сравнению с минимальным тестированием, но не знаю насколько эта инфа достойна доверия.
Эти +30% могли появиться, если там тупо следуют мантре и начинают тестировать геттеры.
Кек
Давно пора это было сделать.
Зачем вообще это надо? Ни разу не пользовался.
Хули тебе не нравится?
>Ты бы лучше сам сказал, что ты админ, а не девелопер.
You build it, you run it - не, не слышали.
>На проде? Пройдя через qa и автотесты?
>Если у тебя такое может пролезть на прод, то у тебя вообще туда может попасть любое говнище, которое ты никакими мониторингами не отловишь, потому что оно чисто на фронтенде будет.
>Ты описываешь очень специфическую проблему и предлагаешь под неё архитектуру переделывать. Это нонсенс, она решается гораздо проще.
Да на проде, да пройдя тесты и мониториг. Тесты не панацея, они снижают шанс что такая херня произойдет, но не устраняют его полностью. У нас была ситуация когда у пользователя отвалился важный функционал, потому что фронт долбился в привелигированный эндпоинт. Заметили по мониторингу, сильный рост 403.
>Соап мог мог работать поверх разных протоколов, естественно он должен был абстрагироваться от деталей HTTP. И сдох он как раз, потому что был слишком замудрёный, и потому что нет никакого смысла делать мультипротокольный протокол (простите), везде есть HTTP.
Чушь, он был переусложнен для простых сценариев. Все эти ноды, роли, фичи. А из протоколов он поддерживал HTTP и SMTP, но второй скорее теоретически, большинство библиотек не поддерживало SMTP.
>А в HTTP уже сразу было дохера кодов, которые должны были возвращаться логикой, и которые никогда бы не вернул веб-сервер типа payment required.
И какая логика должна вернуть 418? И RFC 9457 как раз показывает, что коды HTTP для прикладного API это говно без задач.
>А то ведь можно просто tcp-пакеты гонять, там никаких состояний нет.
Есть gRPC который сознательно работает поверх HTTP/2, там есть цельный мануал почему они так делают. Но при этом, на прикладном уровне коды HTTP они не используют.
>Как я понимаю, awt позволяет использовать разные шрифты. А можно ли как-то вставить свои шрифты?
Кто-то смог вернуть 2007?
java.awt.Font.createFont()
>>заказчик придет и тыкнет пальцем в документацию и скажет должно быть так как написано здесь.
Доки для заказчиков пишут аналитики или тех писатели. Обычно это вообще пдф или докх. Никто не будет ковырять джавадоки. Их вообще кроме как в коде читать неудобно и экспортируют их совсем уж отбитые диды.
Это всё равно часть документации. Удобно это или нет вопрос другой. Будучи частью документации они должны ничего не знать об имплементации (потому что имплементации пишется на основе документации, а не наоборот), а значит они должны быть понятны без кода.
>Уже перестали спрашивать что нового появилось в джаве 8?
Спрашивают, что появилось нового в %LTS_N%.
>Да на проде, да пройдя тесты и мониториг. Тесты не панацея, они снижают шанс что такая херня произойдет, но не устраняют его полностью. У нас была ситуация когда у пользователя отвалился важный функционал, потому что фронт долбился в привелигированный эндпоинт. Заметили по мониторингу, сильный рост 403.
Хуёво сработали QA значит. Мне за 10 лет работы мониторинг ни разу не помогал находить баги в коде. Проблемы с сетью, проблемы с БД - да.
Но опять же, в твоём примере rest бы никак не помешал. И так, и так был бы скачок 403.
>Чушь, он был переусложнен для простых сценариев. Все эти ноды, роли, фичи. А из протоколов он поддерживал HTTP и SMTP, но второй скорее теоретически, большинство библиотек не поддерживало SMTP.
Ну и почему им пользоваться перестали?
>>А в HTTP уже сразу было дохера кодов, которые должны были возвращаться логикой, и которые никогда бы не вернул веб-сервер типа payment required.
>И какая логика должна вернуть 418? И RFC 9457 как раз показывает, что коды HTTP для прикладного API это говно без задач.
Суть HTTP в том, что он не различает веб-сервера и приложения. И как я тебе уже писал пару месяцев назад, нет никакого единого стандарта функционала веб-серверов. Один веб-сервер может уметь отдавать 20 разных кодов и иметь широкую конфигурацию, а второй может быть ультратонкий и возвращать только 200 и 404, если неправильную статику из указанной папочки запросили, а всё остальное передавать напрямую приложению. И со своей идеологией ты даже 404 на неправильный урл не можешь вернуть, ты же не веб-сервер.
Это что, надо код на фронте под функционал веб-сервера подстраивать?
> Фронт под функционал сервера настраивать
Вообще плевать какой бэк, главное, чтобы не менялся. Если же хочешь хорошо, то используй любую конвенцию только укажи её так в описании/документации, чтобы любая макака могла найти.
фронтендер
Ну так только самый последний вкатун не ответит полным чейнджлогом с разрешением до минуты. Не следить за обновлениями джавы это моветон.
Что за шизофрения/жир? Одни только копрорутины с оверхедом x10 чего стоят.
Единственно верный подход.
>>потому что имплементации пишется на основе документации, а не наоборот
Документацию пишут перед релизом всегда, сейчас же эджайл у всех.
Если делать наоборот - то окажется что года 3 назад код может и соответствовал, но после доработок/правок/рефакторингов это уже не так. Поддерживать доку в актуальном виде забывают в 100% случаев.
Только опять же какое отношение это имеет к комментам в коде? У аналитика то и доступа к репе скорее всего нет.
Два вопроса:
1) python умеет отдавать память системе, когда она не нужна. Умеет ли такое хотя бы одна jvm?
2) Можно ли применять socket в разработке для андроида? Нет ли ограничений?
Когда проходил собес пару лет назад уже была 17. Это вопросы не про %LTS_N%, это именно про новую джаву 8.
1) Да, в том числе openjdk. И решает инкоммитнуть память не jvm, а используемый аллокатор/gc в соответствии со своими политиками.
https://shipilev.net/jvm/anatomy-quarks/21-heap-uncommit/
2) Споси в андроид-треде. Насколько я знаю, ограничения есть тольо стандартные линуксовые - т.е. с tcp-сокетами на портах выше 1024 проблем быть не должно.
> комментарии к коду
Ты имел ввиду джавадок? Это не комментарии к коду. Это документация, я уже отметил, что джавадок в принципе ничего о коде знать не должен. Он описывает сигнатуру, которую должны реализовать программисты, но при этом существует даже если никакой имплементации нет в помине.
> документацию пишут перед релизом
Пример того как делать не надо если хочешь нормальный API.
> если делать наоборот, то получишь эффект амёбы
Ага, а если делать по твоему, то получишь потерю обратной совместимости, потому что за 3 дня до релиза при переписывании документации поняли, что изменения затронули те её разделы, которые не должны были затрагивать.
Проще обнаружить ломание обратную совместимость изменяя документацию, чем изменяя имплементацию. В принципе если приходиться переписывать какие-то части документации, а не добавлять новые разделы/новые параграфы, то это красный флаг того, что новая фича, то как её задумывает разработчик, может ломать обратную совместимость.
А так это итеративный процесс. Изменил документацию, имплементирововал, понял что как описал в документации не работает, вернулся к доке и подумал ещё раз как можно реализовать.
Да.
Use case + Scenario + Documentation = Specification
Specification + Implementation = API
Первый раз такую схему видишь?
> Да.
Ну приходи тогда, когда принесёшь что-то побольше яскозал.
> Use case + Scenario + Documentation = Specification
> Specification + Implementation = API
> Первый раз такую схему видишь?
И что эти буквы доказывают?
Нет, это ты подумал. Я прост твои мысли записал.
> ну тогда приходи когда будет больше чем яскозал
А тебе авторитеты собственные мозги заменяют?
> что доказывают эти буквы
Объясни как ты будешь писать писать документацию без спецификации. Как ты напишешь документацию без пошагового описания применения API для решения проблемы пользователя. И как ты опишешь алгоритм использования API без проблемы пользователя.
Если для тебя эти "буквы" ничего не значат, то ты просто не занимался ни разу в жизни созданием API.
Как обычно же. Ну там это, Сычев, сделай чтобы все работало. На пару дней успеешь?
> А тебе авторитеты собственные мозги заменяют?
Нет, если бы ты притащил какого-то авторитета я сказал бы "твой протык?". Мне аргументы нужны.
>Объясни как ты будешь писать писать имплементацию без спецификации.
По изначальной идее. Реализация будет изменяться в зависимости от полученных в процессе разработки новых данных.
> Как ты напишешь документацию без пошагового описания применения API для решения проблемы пользователя.
Когда закончится процесс разработки, финализирую способ применения итогового продукта в документации.
>И как ты опишешь алгоритм использования API без проблемы пользователя.
Проблема пользователя/идея это не документация, то, что она появляется первой не говорит о том, что документация тоже вылезет первой.
Тебе же выше говорили про агиле.
Для клиентских приложений такой подход работает. Для нестабильного API это тоже работает. Если же есть обязательство чтобы релиз 2 не ломал обратную совместимость с релизом 1, то не работает.
>>2991686
> по изначальной идеи
Как это выглядит со стороны. Программист по изначальной идее (по описанию проблемы пользователя) написал имплементацию. Она работает, тесты проходят, всё отлично. Он пишет на её основе документацию с джавакодом, описанием алгоритма использования и какую проблему решает API. После чего он отдает это всё на согласование остальным программистам в команде, техническому лиду, техническим писателям, а первую версию документации может даже глава проекта посмотрит.
И программист получает кучу замечаний:
1. Проблему пользователя он описал неправильно, потому что неправильно понял, но так как она нигде не была записана в явном виде (спецификации же нет, всё в голове у разработчика), то и оказалось, что все её понимали немного по своему.
2. Алгоритм использования API не понравился техническому лиду. Он считает, что можно сделать проще если применить такой-то паттерн и считает, что часть методов вообще не должна в этом алгоритме быть.
3. Документация (на уровне джавакода) не понравилась другим программистам. Они указывают на кучу ошибок, начиная от названия классов и заканчивая более принципиальным вещами то как опасное использование интерфейсов и абстрактных классов ведущих к невозможности расширения в этом месте функциональности в будущем.
И вот программист собрав этот фидбек идёт обратно обратно к имплементации и сносит её к хуям, потому что надо всё переписывать. N месяцев работы коту под хвост. На вопрос как так получилось программист отвечает "я писал по изначальной идеи, а спецификацию планировал написать и согласовать в последнюю очередь". На что логично получает бланк заявления на увольнение.
> тебе же говорили про агиле
Да, и агиле никак не влияет на то как пишется API. Он влияет на то, что каждые 2 недели вы "сверяете часы", согласуете между всеми участниками проекта от менеджеров, до верстальщиков, что двигаетесь правильным курсом и вам нечего/есть чего обсуждать.
Для клиентских приложений такой подход работает. Для нестабильного API это тоже работает. Если же есть обязательство чтобы релиз 2 не ломал обратную совместимость с релизом 1, то не работает.
>>2991686
> по изначальной идеи
Как это выглядит со стороны. Программист по изначальной идее (по описанию проблемы пользователя) написал имплементацию. Она работает, тесты проходят, всё отлично. Он пишет на её основе документацию с джавакодом, описанием алгоритма использования и какую проблему решает API. После чего он отдает это всё на согласование остальным программистам в команде, техническому лиду, техническим писателям, а первую версию документации может даже глава проекта посмотрит.
И программист получает кучу замечаний:
1. Проблему пользователя он описал неправильно, потому что неправильно понял, но так как она нигде не была записана в явном виде (спецификации же нет, всё в голове у разработчика), то и оказалось, что все её понимали немного по своему.
2. Алгоритм использования API не понравился техническому лиду. Он считает, что можно сделать проще если применить такой-то паттерн и считает, что часть методов вообще не должна в этом алгоритме быть.
3. Документация (на уровне джавакода) не понравилась другим программистам. Они указывают на кучу ошибок, начиная от названия классов и заканчивая более принципиальным вещами то как опасное использование интерфейсов и абстрактных классов ведущих к невозможности расширения в этом месте функциональности в будущем.
И вот программист собрав этот фидбек идёт обратно обратно к имплементации и сносит её к хуям, потому что надо всё переписывать. N месяцев работы коту под хвост. На вопрос как так получилось программист отвечает "я писал по изначальной идеи, а спецификацию планировал написать и согласовать в последнюю очередь". На что логично получает бланк заявления на увольнение.
> тебе же говорили про агиле
Да, и агиле никак не влияет на то как пишется API. Он влияет на то, что каждые 2 недели вы "сверяете часы", согласуете между всеми участниками проекта от менеджеров, до верстальщиков, что двигаетесь правильным курсом и вам нечего/есть чего обсуждать.
Не отметил важное. Каждая ошибка на верхнем уровне: проблема, алгоритм, документация. Приводит к каскадному увеличению изменений на более нижнем уровне. Если вы неправильно поняли проблему, то значит и алгоритм решает не то что нужно и его нужно переписывать. Если алгоритм переписали, то часть классов и методов вообще могли исчезнуть, а другие добавиться. Это в свою очередь приводит к тому, что нужно переписывать документацию и имплементацию.
Если где-то наверху ошиблись очень сильно, то вполне может быть ситуация, что всё что внизу будет невалидно реально придется выбрасывать.
Че за шизоуебище написало эту пасту. Ой бляяжь побыстрее бы каникулы закончились...
> Как это выглядит со стороны. Программист по изначальной идее (по описанию проблемы пользователя) написал имплементацию. Она работает, тесты проходят, всё отлично. Он пишет на её основе документацию с джавакодом, описанием алгоритма использования и какую проблему решает API. После чего он отдает это всё на согласование остальным программистам в команде, техническому лиду, техническим писателям, а первую версию документации может даже глава проекта посмотрит.
> И программист получает кучу замечаний:
> 1. Проблему пользователя он описал неправильно, потому что неправильно понял, но так как она нигде не была записана в явном виде (спецификации же нет, всё в голове у разработчика), то и оказалось, что все её понимали немного по своему.
> 2. Алгоритм использования API не понравился техническому лиду. Он считает, что можно сделать проще если применить такой-то паттерн и считает, что часть методов вообще не должна в этом алгоритме быть.
> 3. Документация (на уровне джавакода) не понравилась другим программистам. Они указывают на кучу ошибок, начиная от названия классов и заканчивая более принципиальным вещами то как опасное использование интерфейсов и абстрактных классов ведущих к невозможности расширения в этом месте функциональности в будущем.
> И вот программист собрав этот фидбек идёт обратно обратно к имплементации и сносит её к хуям, потому что надо всё переписывать. N месяцев работы коту под хвост. На вопрос как так получилось программист отвечает "я писал по изначальной идеи, а спецификацию планировал написать и согласовать в последнюю очередь". На что логично получает бланк заявления на увольнение.
Всё это может быть и так, только никакого отношения к документации это не имеет. Согласовать план работы и составить объяснение апи для пользователей это разные вещи.
>>2991700
Никаких предопределённых разработчиками матрицы уровней нет, ты сам себе это придумал. Можно рассмотреть процесс разработки как процесс синхронизации кучи разных идей и взглядов с реальностью и той самой документацией, и исследования всего этого (на начало есть только идея). И документацию тут нет резона делать не последней, так как она зависит практически от всего и любое изменение вне документации будет в большинстве случаев вынуждено быть отражено в изменении документации, и обратно это не пойдёт, так как буквы изменить можно всегда (а вот если в документации пула будет написано, что таски принудительно снимаются через 5 секунд после работы, но метод stop() у Thread больше не существует, реализация не сможет быть подогнана под документацию).
> Как это выглядит со стороны. Программист по изначальной идее (по описанию проблемы пользователя) написал имплементацию. Она работает, тесты проходят, всё отлично. Он пишет на её основе документацию с джавакодом, описанием алгоритма использования и какую проблему решает API. После чего он отдает это всё на согласование остальным программистам в команде, техническому лиду, техническим писателям, а первую версию документации может даже глава проекта посмотрит.
> И программист получает кучу замечаний:
> 1. Проблему пользователя он описал неправильно, потому что неправильно понял, но так как она нигде не была записана в явном виде (спецификации же нет, всё в голове у разработчика), то и оказалось, что все её понимали немного по своему.
> 2. Алгоритм использования API не понравился техническому лиду. Он считает, что можно сделать проще если применить такой-то паттерн и считает, что часть методов вообще не должна в этом алгоритме быть.
> 3. Документация (на уровне джавакода) не понравилась другим программистам. Они указывают на кучу ошибок, начиная от названия классов и заканчивая более принципиальным вещами то как опасное использование интерфейсов и абстрактных классов ведущих к невозможности расширения в этом месте функциональности в будущем.
> И вот программист собрав этот фидбек идёт обратно обратно к имплементации и сносит её к хуям, потому что надо всё переписывать. N месяцев работы коту под хвост. На вопрос как так получилось программист отвечает "я писал по изначальной идеи, а спецификацию планировал написать и согласовать в последнюю очередь". На что логично получает бланк заявления на увольнение.
Всё это может быть и так, только никакого отношения к документации это не имеет. Согласовать план работы и составить объяснение апи для пользователей это разные вещи.
>>2991700
Никаких предопределённых разработчиками матрицы уровней нет, ты сам себе это придумал. Можно рассмотреть процесс разработки как процесс синхронизации кучи разных идей и взглядов с реальностью и той самой документацией, и исследования всего этого (на начало есть только идея). И документацию тут нет резона делать не последней, так как она зависит практически от всего и любое изменение вне документации будет в большинстве случаев вынуждено быть отражено в изменении документации, и обратно это не пойдёт, так как буквы изменить можно всегда (а вот если в документации пула будет написано, что таски принудительно снимаются через 5 секунд после работы, но метод stop() у Thread больше не существует, реализация не сможет быть подогнана под документацию).
> Да, и агиле никак не влияет на то как пишется API. Он влияет на то, что каждые 2 недели вы "сверяете часы", согласуете между всеми участниками проекта от менеджеров, до верстальщиков, что двигаетесь правильным курсом и вам нечего/есть чего обсуждать.
Он влияет на подвижность. Если есть негибкий контракт, то он либо будет завершён в изначально оговоренных условиях, либо не завершён, и в любом случае проекту можно назначить одну неизменяемую документацию, написанную в момент написания контракта. А если агил, то пока завершится работа, всё поменяется миллион раз, и миллион раз документацию придётся менять.
> это не имеет отношения к объяснению как работает API, это про согласование работы
Как согласовать то, что не описано? А если описываешь, то по сути создаёшь спецификацию. Можно конечно согласовывать на кухне, устно, с пончиком во рту (сам так делал), но результат будет плачевным, потому что через день вы с техническим лидом будете помнить этот разговор по разному.
> документацию нет смысла делать не последней, так как она будет зависеть от всего
Верно, но знаешь что ещё будет зависеть от всего включая документацию? Имплементация. Если пример выше где сначала сделали кучу кода, потратили месяцы работы, а потом решили наконец-то это описать в спецификации и согласовать и обнаружили, что каждый из участников представлял себе API по разному не является обоснованным, то я не знаю как по другому объяснить, что спецификацию нужно писать и согласовать до имплементации.
> если в документации написано одно, а в имплементации этого не достичь, то нужно переписывать документацию
Всё так, но здесь то в чем проблема? Как ты сам сказал буковки всегда можно поменять. В этом и смысл, что менять документацию легче чем имплементацию на этапе разработки. А вот удалять 5000 строчек кода потому что делал что-то не то гораздо сложнее.
>>2991706
Всё так и есть, но опять же я не понимаю почему из-за измененных требований изменение документации это проблема, а изменение имплементации нет. Или если нет документации, то изменение требований не требует изменять уже написанную имплементацию?
Я ещё раз повторяю, согласование работы людей и объяснение итогового апи для других людей это разные вещи. Согласоваться можно текстово, можно подробно, но нет никакого смысла писать юзер-гайды (что и является качественной документацией) на то, что ещё не создано.
Никто не говорит отказаться от согласования и начать понимать каждому всё по своему, подход зафиксировать все идеи в тексте имеет место быть, никто не говорит, что изменение кода это не проблема.
Проблема вот в этом
> по сути создаёшь спецификацию
Юзер (любой компетенции, хоть юзер принтера, хоть юзер апи для разработки сборщиков мусора) хочет видеть картинку, что всё получилось после выполнения действий, хочет примеры использования, объясняющие всё досконально как для дауна, хочет видеть грамматически правильно построенный текст отформатированный в .md, хочет подсказки. Согласование работы всего этого не требует. Это пересекается, но есть разница.
> согласование нужно, но юзер-гайды нет смысла писать
Если согласны про согласование спецификации, то степень подробности спецификации действительно дискуссионна. С одной стороны чем подробней тем ниже вероятность ошибки, с другой стороны это требует больших усилий, возможно больших чем исправление ошибки рассогласования.
Тут проще найти какое-то коллективное решение. Например у нас сейчас рисуют диаграммы алгоритмов и согласовывают, но раньше в принципе хватало пронумерованного списка вместо диаграмм. Если все согласны с таким уровнем подробности спецификации (внутренней спецификации), то всё ок.
Ты до конца-то дочитал? Помимо разницы в необходимом уровне качества есть разница в том, что документация учит, а разработчикам друг друга учить не надо.
> Всё так и есть, но опять же я не понимаю почему из-за измененных требований изменение документации это проблема, а изменение имплементации нет. Или если нет документации, то изменение требований не требует изменять уже написанную имплементацию?
Проблема, но изменение реализации избежать нельзя, а вот документирование можно отложить до лучших времён.
Я дочитал до конца, я думал что это всё часть одного тезиса про подробность спецификации.
> документация учит, а разработчикам друг друга учить не надо
Разработчики не телепаты, то что очевидно тебе другому разработчику может быть не очевидно. Особенно другому разработчику, который как и пользователь (который тоже вообще-то разработчик если мы про API) первый раз видит проект. Из недавнего ко мне пришел разработчик, который не знал как с помощью гредл собрать клиентское приложение используя наш API потому что мы эту информацию не добавили во внутреннюю спецификацию. Можно было кекать и начать мерятся письками профессионализма, или можно было добавить 10 строчек в документацию и закрыть этот вопрос для всех пользователей. Я выбрал оба варианта.
В общем, я не вижу того что не нужно учить разработчиков пользоваться API. В этом один из смыслов даже внутренней спецификации, которую используют люди с разным уровнем погруженном и в проект.
>>2991738
Конечно, это разные вещи. Документация лишь часть спецификации.
>>2991741
Тогда будет вот эта ситуация >>2991696
Ещё раз блядь, цель документации — научить продукту, цель всего того что пишется для синхронизации, как ни странно, синхронизироваться. Документация может быть подцелью, но никак не заменой. В этом не просто нет смысла, это ещё и вредно. Ты предлагаешь вместо достижения цели А достигать цель Б, что позволяет выполнять цель А на 99%. Никто не говорил что учить не надо, сказано было что это не главная цель.
> Тогда будет вот эта ситуация >>2991696
Отказ от замены цели А на Б не отменяет цель А.
> цель документации научить продукту
Мне кажется у нас проблема терминологии.
1. Спецификация - описание продукта, которые состоит из проблемы пользователя (use case) + сценария использования (scenario) + описания сигнатуры (вообще тоже называют docs, но пусть будет javadocs для того, чтобы различать).
2. Сценарий использования (scenario) описание как работать с продуктом, чтобы решить проблему пользователя (видимо это ты имеешь ввиду под документацией).
Понятное дело, что описывая как предполагается использовать API для решения проблемы пользователя (этот метод должен быть вызван первым, этот метод вторым), то читающий получает необходимые знания, чтобы использовать API.
> Ты предлагаешь вместо достижения цели А достигать цель Б, что позволяет выполнять цель А на 99%.
Я предлагаю написать хороший API. Для этого нужна синхронизация между участниками, для этого нужно описание продукта, а описание продукта это и есть спецификация.
Про научение же: это всего лишь часть спецификации, тот самый scenario. Степень его проработки на этапе разработке дискуссионный, но то что нужно объяснить коллегам в какой последовательности вызвать методы у API кажется очевидно. Это же важная часть описания API и они не телепаты, чтобы просто догадаться об этом.
> Спецификация
Техническая хуйня аля этот метод не имеет сайд эффектов, зови сколько хочешь и как хочешь. Под документацией я имел вообще всю сопутствующую продукту литературу.
Но вообще не в терминологии дело.
>имплементации пишется на основе документации, а не наоборот
Изначальный тейк.
>имплементацию лучше делать если есть спецификация/документация (в зависимости от того что понимать под терминами)
Ты доказываешь.
Окей, как писать имплементацию без описания продукта/спецификации? Приведи пример
Ну хорошо, допустим. Каким образом сложность
>писать имплементацию без описания продукта/спецификации
доказывает
>имплементации пишется на основе документации, а не наоборот
?
Ну, ещё раз напиши имплементации чего угодно без описания этого чего угодно. Ты всегда используешь спецификацию при имплементации, просто в случае примера >>2991696 эта спецификация в голове у разработчика, он ей ни с кем не делиться, постоянно что-то забывает в ней и допридумывает того чего изначально не было, но спецификация есть. И она возникла в голове разработчика раньше чем появился код в IDE.
Ты подменяешь термин. Сначала определяешь спецификацию так
>1. Спецификация - описание продукта, которые состоит из проблемы пользователя (use case) + сценария использования (scenario) + описания сигнатуры (вообще тоже называют docs, но пусть будет javadocs для того, чтобы различать).
потом используешь так
>спецификация в голове у разработчика
И разница не только в масштабе, но и в целях.
Ну, описание продукта в голове у разработчика. Или он пишет код и не знает зачем он его пишет? Он знает какую проблему должна решить ещё не написанная функция - знает. Это use case. Он знает как эта функция будет применяться, чтобы решить проблему - знает. Это scenario. Он знает её сигнатуру перед тем как написать - знает. Это есть javadocs.
Вот тебе и готовая спецификация, просто в голове у разраба.
Если бы было наоборот (имплементации -> спецификация), то разработка API выглядела бы как
1. Закрыть глаза, положить руки на клавиатуру
2. Открыть глаза увидеть появившийся код (имплементацию)
3. Описать код пытаясь понять зачем он нужен и как его использовать (спецификация)
Ну ладно, допустим по спецификации. Документация тогда получается не часть её, как минимум потому что слово документация подразумевает наличие документов.
>Мне за 10 лет работы мониторинг ни разу не помогал находить баги в коде.
Не баги, а проблемы. Релиз откатили, и потом уже нашли баг.
>Ну и почему им пользоваться перестали?
Я бы спросил, чем ты читаешь, но не буду. Ты сам процитировал кусок про проблемы с переусложнением для простых сценариев.
>Суть HTTP в том, что он не
создавался для прикладного API. Приложению надо определять свои коды ошибок, а в HTTP нет стандартного способа это сделать. А в нормальных протоколах - есть.
>Это что, надо код на фронте под функционал веб-сервера подстраивать?
У тебя фронт и так будет подстраиваться под функционал твоего бекенда и парсить 9457 или самопальный формат ошибок.
На хабр карьере расположено 2 вакансии(появились за последний месяц), одна на мидла, вторая не обозначена. Описание полностью одинаковое. Требования на пикче. Стоит ли пробовать на не обозначенное?
не обозначено же! значит не для тебя вакуся малыш
>>люди боятся JavaScript, json и xml
Лично меня напрягли Vaadin и Glassfish на жава 8. Оракл тож пованивает (наверняка это хранимки)
Ну и жаваскрипт при таком раскладе это явно не рякт, а жквери.
Поддержка пятой линии для пенсионера это. Разрабу там негде развернуться.
У нас чары проверяют опыт работы, требуют подтверждающие документы. Просто вписать себе год работы в резюме по крайней мере в моей конторе это провал.
>>Суть HTTP в том, что он не
>создавался для прикладного API. Приложению надо определять свои коды ошибок, а в HTTP нет стандартного способа это сделать. А в нормальных протоколах - есть.
Правильно, тогда не было прикладного веб-API, точнее его функционал реализовывали веб серверы, которые отдавали статику. Потом сценарии усложнились, и веб-серверам пришлось предоставить генерацию контента внешнему коду, потому что конфигурацией сервера это уже не решалось. Но это не отменяет того, что клиенту строго похер, ему 404 возвращает веб-сервер или приложение за ним.
К тому же сейчас обработка веб-запроса это многоступенчатый процесс, и совсем не ясно, где тут проводить границу между трансфером и приложением.
>>Это что, надо код на фронте под функционал веб-сервера подстраивать?
>У тебя фронт и так будет подстраиваться под функционал твоего бекенда и парсить 9457 или самопальный формат ошибок.
Ты не понял. Давай я тебе разверну.
Вот у тебя есть веб-сервер, например apache, с фреймворком и роутингом динамических url-ов. Фреймворк видит, что запрошенный url не подходит ни под один шаблон, и возвращает 404.
Тут к тебе приходит начальник и говорит, что из-за гойды и санкций использовать апач больше нельзя, а можно только отечественный вебсервер ростабурет, который поддерживает сайты только на 1с и кумир. И вот ты переписываешь свой сервер на 1с и выясняешь, что никаких фреймворков для веб там нет, а сервер просто в точку входа передаёт тебе распарсенный объект ГиперТекстовыйПередачныйПротоколЗапрос, у которого есть поле УниверсальныйРесурсныйЛокатор. Ты немного седеешь, много материшься, но в итоге пишешь свой роутинг, который по урл понимает, куда передать запрос. Но вот незадача, тебе нельзя на неправильный url возвращать 404, ведь это же уже не веб-сервер, и не фреймворк. И поэтому тебе ещё и фронтенд приходится переписывать, ведь у тебя поменялся контракт.
Ты не отдупляешь что тебе пишут. Я тебе уже раза 3 на разный лад писал, что дизайн HTTP не подходит для реализации API как транспортный уровень - ок. А ты мне втираешь какую-то дичь про вебсервер, 1С и прочую херню.
Но ты это никак не можешь доказать.
Понятно в соап и грпц нет использования кодов, помру что коды это семантика, которая на уровне этих протоколов неизвестна.
Я в принципе могу понять желание использовать grpc в распределённом приложении чтобы меньше париться, но, например, делать такой api публичным - это просто некрасиво, потому что лочит клиентов в выборе клиентов (прошу прощения).
И я уже много лет пишу веб с использованием рест, и единственная проблема, с которой я столкнулся, это когда кто-то зачем-то на одну из виртуалок поставил webdav в iis (я дотнетчик), а он сжирал все запросы кроме гет и пост.
Но эта проблема уже не существует в новых asp.net, где используется kestrel.
Библиотеки на js типа axios или, прости г-ди, jquery, да и тот же fetch, нормально позволяют обрабатывать разные коды ответа. Можно под свою схему написать wrapper, который удобно использовать.
На бэкэнде я просто пишу throw new BadRequestException(message), и Asp.Net мне сам генерирует ответ клиенту.
Почему мне надо изъебываться и не использовать существующие фичи бэка и фронта, при том, что оно нормально работает?
Хочу к этому добавить, что ответ с кодами ошибок - это не нормальная ситуация. Например, запрос на получение сущности по Id возникает не на пустом месте, этот id клиенту кто-то должен быть выдать в предыдущих запросах. И если тут вдруг сущности нет, то либо её за это время кто-то стёр, либо у тебя проблема с данными или кодом. Поэтому тот же приведённый тобой в пример мониторинг помог бы увидеть проблему, в то время как 200 прошли бы незамеченными.
склоняюсь к тому чтобы нахуй Optional выпилить и проверку на null просто сделать
Как же поздно ораклы поняли свою ошибку с нулевым DX в джаве, но вот только поезд ушел и все молодые разработчики ушли в го/дотнет/раст где первоклассные тулзы из коробки, готовы работать в твоей консольки без ебли с javac, XML или скриптами градла.
А эти молодые разработчики и тулзы сейчас с нами в одной комнате? У шарпа из этого набора хоть какое-то подобие нормальных тулзов и ну и кого нет инфраструктуры джаббы и IntelliJ которая изначально под джаву была и теперь под другие языки стараются подпиливать.
Тут не лучше/хуже, у тебя просто банально неправильный код написан.
Код в параметре .orElse выполняется сразу же при создании опшонала, поэтому у тебя код просто всегда будет ставить builder.setError
Если ты хочешь отложенно выполнить, то у опшонола есть методы с консьюмерами .orElseGet и вот этот код уже будет выполняться отложенно.
>>2992045
Нет, просто BPMN, Glassfish - это древнее говно мамонта, и никакой высокой нагрузкой там не может пахнуть. Это просто лютое легаси, которое обычно в галеры отдают, сам на таком работал.
Попробуй сходи, пока тебе прямо не сказали что не берут эти фильтры по опыту всерьез принимать нельзя, если хочешь этот самый опыт получить.
GET /users?search=id:1,2,3
А какие документы если на удаленке работал где-нибудь на апворке? Бред какой-то.
Не знаю, я просто спросил у чара когда попалось резюме с 10 годами стажа которое выглядело от человека первый раз в жизни пишущего резюме с 0 полезной информацией будем до мы проверять предыдущие места работы кандидатов. Мне сказали, что если кандидат проходит техническое собеседование, то чары долбятся во все компании указанные в резюме, чтобы подтвердить стаж работы кандидата.
>резюме с 10 годами стажа которое выглядело от человека первый раз в жизни пишущего резюме
так у него не закрадывалась мысль в голове что это нормально? Программист, который 10 лет не меняет место работы по умолчанию не умеет писать резюме, потому что он этого и не делал никогда в жизни.
По поводу прилично выглядящего CV - я сам используют Europass и всем рекомендую
https://europa.eu/europass/en/create-europass-cv
У него там 5 мест работ было. 10 лет это совокупный стаж.
Ахуительные истории. Че за пиздец блять, какого хуя вообще опыт работы хоть в чем-то роляет?
Есть требования, их задача обеспечить, что бы мы получим кадра им соответствующего. 3 года минимум, мне сказали сразу выбрасывать резюме где стаж написан меньше (я им помогаю отсеивать резюме, которые прошли первоначальную воронку).
Хз, я вот часть с выбросом ошибки в отдельные сервисы пихал. И вот его уже себе инжекчу и там метод который возвращает @NotNull. Тип getUser(username)
>Есть требования
Ну обычно требуется, чтобы чел понимал специфику работы. Связь между опытом работы и конкретно тем, что кандидат его имеет это понимание не так велика. Хотя ладно, вы ж тупые хрюши, нормальное решение - это не для вас. Мы дрочим алгосы и опыт работы.
>я им помогаю отсеивать резюме, которые прошли первоначальную воронку
Серьезно? Твоя работа сводится к тому, что может банальный фильтр хх? Пиздец.
> пиздец
МЯУ, тоже не понял при чем здесь я. Мотивация была уровня: он же к тебе в команду пойдет, но что-то я хз как чтение резюме "юной, но способной Ани с 6 месяцами стажа" реально помогает найти лучшего кандидата.
> чел понимал специфику работы
Это тоже проверяем. Я в общем это и проверяю тем что читаю резюме и совсем, то что мимо выкидываю.
Ты че мяукаешь... Я побукать хотел, злость выместить там, а ты...
Еще вдохновения нет чет. Надо начать со структуризации, по DDD ubiquitous language все дила... Нооо не идет.
Ты че, даун?
>Хотя ладно, вы ж тупые хрюши, нормальное решение - это не для вас. Мы дрочим алгосы и опыт работы.
Ну ты дрочи свои алгосы, а вот этот помощник эйчарки тебя просто отсеет потому что список технологий посимвольно не совпал, а у чела который дрочил резюме - совпал, его и пригласят
Что сейчас лайвкодят на мидла? Три года назад устраивался на джуна так считал количество слов в строке, писал бинарный поиск, а мидлу что дают?
Жыр.
> У шарпа из этого набора хоть какое-то подобие нормальных тулзов
Нет никакого подобия. У них там проекты на ебучем симейке неиронично собираются.
Если честно хуйнёй какой-то скуфц занимается. mvn archetype:generate и через минуту у тебя уже всё запускается с поддержкой репозиториев, зависимостей и прочих радостей.
Он-то хуйнёй занимается, это понятно. Но, ты даже не попытался прочесть и понять, о чём там вообще.
А тот долбоёб просто не в курсе, что на свете существует Groovy.
Зачем ты приплёл мавен какой-то, репозитории, зависимости и прочее?
Чел хочет простые проекты запускать без компиляции в класс-файлы. Но, для этого есть груви. Который ещё и поприятнее джавы гораздо (именно для простых проектов, для сложных уже нет).
Затем что это понадобится, и придётся перетаскивать код в систему сборки. Такой же мотивации следовали когда делали аннеймед классы, чтобы они могли быть точкой входа как для хелло ворлда, так и для какой-нибудь ебанутой джава ос.
Вот что интересно это зачем ты приплёл какой-то груви, если джеп для джавы предназначен. Литералли ситуация с той картинки, где чел в туалете подходит вплотную к писсуару другого, начинает тоже ссать, и говорит, что ему надо перейти на питухон.
Ничего не понадобится.
Не надо тут заниматься преждевременной эякуляцией оптимизацией - она корень всех зол.
Речь о простых проектах - хелловорлдах и протототипах, тестировании и прочем.
Это известная тема, и появилась она ещё когда ты пешком под стол ходил. И решалось это тогда через bean shell и прочее подобное. Груви появился уже позже.
А груви здесь при том, что валидный джава код является так же и валидным груви кодом. Чел хотел запускать джава код без компиляции - груви это делает.
А тебе надо расширять кругозор. И учиться читать и понимать прочитанное.
Какая ещё преждевременная оптимизация? Почему не понадобится, потому что тыскозал? Что ты несёшь, осёл?
Я, в общем-то, сразу понял, что ты совсем зелёный инцел.
Но, решил проверить, на всякий случай. И не ошибся.
По делу я тебе уже всё сказал.
Груви решает обозначенную проблему. Причём, решает в разы лучше, чем то, что тот чел предлагает. И делает он это уже лет 15 примерно. Тот чел написал хуйню, потому, что вообще не знаком с этой темой.
Мавен и прочие средства ускорения создания обычных проектов на джаве тут вообще не при делах, это совсем другая проблема.
И каким образом левая тулза в виде левого языка программирования решает проблему сложности использования левых тулзов в виде систем сборки для работы с многофайловыми проектами?
Всё так. У меня коллега откровенных проходимцев пихает на собес если в резюме есть слово про редкую технологию с которой мы работаем.
помощник чара
>>2992907
Я реально не верю, что кто-то продолжает давать алгосы. Мы даём тестовое написать API по ТЗ. Нафига нас разраб умеющий в бинарный поиск если он сует интерфейсы в API, называет переменные как долбон и не понимает в чем проблема?
А помощник чара в курсе, что API по ТЗ может сгенерить LLM? Если давать тестовое то только в виде лайвкодинга прямо на первом собесе.
Ну тогда слив принят, гуляй.
В смысле, чтобы не на спринге?
Микронавт?
> библиотек
Ну, например, на чём http сервер? На чём клиент? Netty?
Рест или какой-то двоичный протокол, типа протобуфа?
И на чём таки DI, если это не спринг? Или как-то иначе эта проблема решается?
> Ну, например, на чём http сервер? На чём клиент? Netty?
> Рест или какой-то двоичный протокол, типа протобуфа?
Всё это есть в виде отдельных библиотек.
> И на чём таки DI
Нинужен, но есть жуйсе.
>в виде отдельных библиотек
Каких именно, просто для примера?
Ну, и netty - вполне себе библиотека, хоть и называется "фреймворком".
>Мы даём тестовое написать API по ТЗ.
Это понятно, но на работу берут не после тестового, а после собеса с лайвкодингом. Тестовое это просто доп воронка перед собесом. Вот меня и интересует что задают, я просто не знаю стоит ли задрачивать задачи с бинарным деревом и обходом графа в ширину и глубину или это ту матч для мидла за 230-260к
В яндекс тебе путь точно закрыт, там от 4 алгоритмических интервью, где 2 последних проходят очно и ты решаешь задачи маркером на доске при всех.
https://yandex.ru/jobs/pages/dev_interview
Ну, гуглится-то много разного, вообще-то.
Вы этот java-express реально в проде используете? И давно?
А эти собеседующие из яндекса решат мою задачу?
>>2993109
Задача простая, пусть они не говорят, что не справились. От информации о том, что работаем с многочленами, надо абстрагироваться. Надо просто придумать, как делить данное uint64_t пополам и что дальше делать.
В айти долбоебы годами задрачивают поиск в ширину, которому в универе уделяется одна-две пары, ничего не знают кроме этого и ебут нам мозги.
Буду алгоритмическим собеседующим задавать встречную задачу про степень многочлена. Никто из них не решит, т.к. для этого нет стандартного решения. Это криптография и теория кодирования. Однако задача простая.
Я на бинарном протоколе сижу вообще-то. Ты спросил просто про хттп, я тебе ответил.
Да, спасибо, я понял. Выглядит интересно, а что там с производительностью - неизвестно, надо смотреть.
А в случае бинарного протокола что ты используешь в качестве сервера? Тут, мне кажется, как раз кейс для netty. Оно специально для этого и делалось.
Ты не можешь добавить новый метод в интерфейс в версии 2 не сломав обратную совместимость с версией 1. Фактически ты подписываешь контракт, что интерфейс никогда не измениться. И это проблема с точки зрения расширения функционала API. Она легко решается использованием финальных классов, в которые можно добавлять новые методы без проблем с обратной совместимости.
Поэтому если кто-то пишет клиентский API и начинает использовать интерфейсы и не объясняет почему он решил отрубить себе возможность расширять API в этом месте, то это красный флаг.
>>2993090
Помощник чара знает об этом. Может быть ты и прав, нужно будет подумать об этом.
>>2993123
Так я вообще не понимаю зачем, что на лайвкоде, что оффлайн давать тестовое состоящее из алгоритмов. Как это коррелирует с реальной работой? Я всего один раз не нашел готовый алгоритм и реализовывал сам за 4 года работы.
Так интерфейс на то и предназначен, чтобы дать пользователям ручку, не показывая реализацию. Не все интерфейсы предназначены для расширения пользователями в принципе.
>Ты не можешь добавить новый метод в интерфейс в версии 2 не сломав обратную совместимость с версией 1.
Почему не могу? Беру и добавляю, а в классах имплементирующих этот интерфейс реализую
Ой больно-то надо идти в яндекс. Я прям рыдаю, трагедия мирового масштаба. 3 тыщи долларей или сколько там в месяц упустил. Как я после такого выживу, это же невозможно перебить таким же или большим оффером.
> дать юзеру ручку не показывая имплементацию
Они имплементацию и не увидят, ты же не исходники программы отдаешь.
> не все интерфейсы предназначены для расширения
Ни один интерфейс не предназначено для расширения. Расширение и интерфейс это как секс и френдзона - не пересекаются.
API предназначен для расширения, потому что завтра придет заказчик и скажет, что надо ещё вот такую фичу добавить. И уда ты её будешь добавлять в имплементацию интерфейса? Никуда, потому что твоя имплементации интерфейса не может делать больше чем указано в интерфейсе.
Единственное применение интерфейсов это API Provider, но для этого нужно, чтобы разраб умел отличать Client API от API Provider.
>>2993146
Окей, что происходит с имплементацией интерфейса из версии 1 пользователем? А точно, она в красном, потому что теперь она тоже должна имплементировать новый метод. У юзера на уровне компиляции сломана обратная совместимость после твоих изменений.
Да, это интересно.
> Они имплементацию и не увидят, ты же не исходники программы отдаешь.
"не показывая реализацию" это не про защиту кода, а про полиморфизм.
> Ни один интерфейс не предназначено для расширения. Расширение и интерфейс это как секс и френдзона - не пересекаются.
Оговорился, имелась в виду реализация.
> И уда ты её будешь добавлять в имплементацию интерфейса?
Зависит от ситуации. В общем случае сделаю новую реализацию интерфейса.
> полиморфизм
> не показывать имплементацию
Объясни мотивацию? Пользователь получает финальный класс, а не интерфейс и что он узнает об имплементации такого чего не видел в интерфейсе?
> реализация не предназначена для расширения
Не все, но общий случай именно что расширение, потому что клиентский API всегда сталкивается с требованием добавить больше функциональности.
> сделаю новую имплементацию интерфейса
Тебе нужен новый метод. Не менять старый метод, а новый метод, которого не было в интерфейсе. Было у тебя например в интерфейсе takePhoto(), а теперь нужно, чтобы был ещё метод takeSnapshot(). Каким образом новая имплементации того же интерфейса добавит этот новый метод?
> Объясни мотивацию?
Дядь, ты чего. Основной принцип ООП. Вот объяснение для самых маленьких: https://javarush.com/groups/posts/polimorfizm-v-java
И к слову это как раз в том числе для сохранения обратной совместимости используется, чтобы новые фичи писались под реализациями интерфейса и работали со старым кодом.
> Не все, но общий случай именно что расширение, потому что клиентский API всегда сталкивается с требованием добавить больше функциональности.
Ну давай по буквам, раз не понятно. Вместо "расширения" должно быть "реализации". Итог: "не все интерфейсы предназначены для реализации пользователем".
> Тебе нужен новый метод. Не менять старый метод, а новый метод, которого не было в интерфейсе. Было у тебя например в интерфейсе takePhoto(), а теперь нужно, чтобы был ещё метод takeSnapshot(). Каким образом новая имплементации того же интерфейса добавит этот новый метод?
У меня изначально будет интерфейс CameraAction и реализация Photo и новая Snapshot.
Я думаю, что ты его не понял.
Он имел в виду, что когда ты отдаёшь интерфейс клиенту, ты теряешь контроль над его реализацией. И, далее, если ты интерфейс поменял (в одностороннем порядке), то _все_ прошлые реализации автоматически ломаются. Подразумевается, что клиент (каким-то обазом) получил новый интерфейс, но, по какой-то причине не может/не хочет менять свою реализацию интерфейса. Ситуация несколько притянута за уши, но не слишком.
Если коротко, то, речь идёт примерно о букве I в слове SOLID.
Ну, и, отчасти, о букве S.
Я прекрасно его понял, я и объясняю что опасность такой поломки не проблема, и уж точно не то, чего стоит боятся настолько, чтобы в фанатичном приступе выпиливать все интерфейсы, которые гораздо больше обратной совместимости сохраняют, чем ломают.
Чтобы ещё было понятнее - в Го, например, считается хорошей практикой делать интерфейсы из одного метода. Именно по этой причине. Нет, я не призываю на джаве делать так же.
https://jdbi.org/
это посимпатичнее spring jdbc
>Что насчёт SQL маппера, типа mybatis?
не вижу смысла, ускорения и упрощения нет, а возможности ограничиывает
Да, выглядит интересно, надо будет посмотреть поближе.
> полиморфизм
Применим из моей практики чуть менее чем никогда. Окей, пускай так, спорить что он в принципе имеет смысл не буду.
> не все интерфейсы предназначены для имплементации пользователем
Пользователю об этом рассказал? А то он не в курсе, потому что твой интерфейс он реализовать может без всяких проблем, а потом засунуть как вход в какой-нибудь твой метод. Зачем? Потому что он может. И ты должен быть к этому готовым.
> у меня будет изначально интерфейс и я добавлю к нему две имплементации
У тебя интерфейс не умеет делать snapshot, он умеет делать photo. Ты понимаешь, что это будут две разные структуры данных? Помимо этого ты заставляет пользователя выбирать: или то или другое. А что если пользователю нужно и то и другое?
> Применим из моей практики чуть менее чем никогда. Окей, пускай так, спорить что он в принципе имеет смысл не буду.
Это камень в огород разве что твоей практики.
> Зачем? Потому что он может. И ты должен быть к этому готовым.
Ну тогда иди предъявляй разработчикам джавы, что они добавили возможность подсчитать хеш .jar файла библиотеки и выкидывать ошибку при его изменении, и что теперь можно писать код, который при обновлении сломается. Кретинизм пользователя это не моя проблема.
> У тебя интерфейс не умеет делать snapshot, он умеет делать photo.
Апи обычно на конкретной структуре данных не завязывают. Если есть кардинальные различия и нельзя реализовать тот же метод по другому (на избежание чего в том числе и направлена правильная архитектура), то делаю новый интерфейс, опционально более абстрактный и депрекейчу старый.
> А что если пользователю нужно и то и другое?
Ты что, еблан? Две переменных значит заведёт.
> кретинизм пользователя не моя проблема
> буквально даёт публичный интерфейс в API
Охуенно братан. Сколько клиентов у твоей библиотеки? Один?
> делаю новый интерфейс
> депрекейчу старый
То есть у пользователей всё в жёлтом и они читают причину, а там написано "захотели добавить новый метод, а интерфейсы этого не позволяют, поэтому короче переписывание свои клиенты даже те кому новая функциональность вообще не нужна". Умный ход, примерно раз в релиз придется клиентам переписывать код если они не хотят сидеть на депрекейтат типах если я правильно понял.
> две переменные пусть заведет
Охуенно. Когда понадобиться третий метод добавить, то пусть заведет третью переменную. А потом четвертую.
> правильная архитектура
на кончиках пальцев.
> на кончиках пальцев.
> Охуенно братан. Сколько клиентов у твоей библиотеки? Один?
Ты может по делу что-то высрешь?
> То есть у пользователей всё в жёлтом и они читают причину, а там написано "захотели добавить новый метод, а интерфейсы этого не позволяют, поэтому короче переписывание свои клиенты даже те кому новая функциональность вообще не нужна". Умный ход, примерно раз в релиз придется клиентам переписывать код если они не хотят сидеть на депрекейтат типах если я правильно понял.
Альтернативы? "Знал бы где упасть — соломку б подстелил". Модульность и контролируемые брекинг ченджи, которые не перерастают в поломку совместимости.
> Охуенно. Когда понадобиться третий метод добавить, то пусть заведет третью переменную. А потом четвертую.
А что не так? У тебя переменные по талонам что-ли?
>"не показывая реализацию" это не про защиту кода, а про полиморфизм.
нет, это инкапсуляция, полиморфизм - это множество имлементаций одного интерфейса
>что происходит с имплементацией интерфейса из версии 1 пользователем? А точно, она в красном, потому что теперь она тоже должна имплементировать новый метод.
Ну да, на то у тебя и версионирование апи, нахуй ты тогда версии апи ведешь, не хочет пользовать апи реализовывать новый метод - идет нахуй на старую версию апи, как раз таки обратная совместимость ничуть не сломана, старые методы неизменены, в отличие от того что ты там городишь классами переписывая логику старого кода. Новые методы появляются не случайно, они дают клиенту новый функционал в нужной ему предметной области, если клиент не хочет реализовывать метод он может написать в нем выброс эксепшена и нигде не вызывать.
Пересекающиеся вещи, инкапсуляция больше о том, как это выглядит, полиморфизм о том, какие позитивные последствия. Но по сути да, я в момент написания того поста думал о примере инкапсуляции.
> по делу
Клиент всегда реализует твой интерфейс. Всегда. Единственный способ себя как разработчика API защитить от этого это в тех методах, что принимают интерфейс проверять, что реализация интерфейса одна из ожидаемых. Прямо через Class.packageName и погнали.
Про то, что интерфейсы ограничены для расширения функциональности (и они должны быть ограничены в клиентском API, потому что есть ещё SPI) я уже сказал.
> Альтернативы?
Финальные классы. Можно расширять функциональность до бесконечности. Из примера выше, просто бы добавили метод getSnapshot, который бы вернул новый тип Snapshot. Для существующих клиентов вообще ничего не изменилось. Для тех кому нужна новая функциональность достаточно добавить вызов нового метода к существующей логике работы без нужды заниматься поддержкой множества имплементацией одного интерфейса в разных переменных.
> переменные по талону
Просто это не так удобно как, ну знаешь, не создавать новые переменные.
>>2993255
> если клиент не хочет реализовывать метод он может написать в нем выброс эксепшена и нигде не вызывать
Я ОРУ НАХУЙ! Вот она "правильная архитектура", наконец-то нам показали её.
>Вот она "правильная архитектура"
Так зачем тебе версионирование апи? У тебя ничего не меняется, ебош без циферок.
>Финальные классы. Можно расширять функциональность до бесконечности. Из примера выше, просто бы добавили метод getSnapshot
И этот человек что-то там кукарекал про SOLID выше))0
> Клиент всегда реализует твой интерфейс. Всегда.
> кретинизм пользователя не моя проблема
> в тех методах, что принимают интерфейс
Те интерфейсы, что передаются пользователем не создают проблемы расширения сами по себе. Методы этого интерфейса можно рассматривать как функциональные аргументы метода, куда интерфейс передаётся. В таком случае если интерфейсу понадобиться изменение сигнатуры, то эта же ситуация будет отражена без использования интерфейса, только аргументы будут обосраны всякими Function5<Consumer<Throwable, Zalupa>>.
> Из примера выше, просто бы добавили метод getSnapshot, который бы вернул новый тип Snapshot.
А какое вообще тогда отношение этот пример имеет к интерфейсам? Неудобность забивания гвоздей микроскопом не доказывает бесполезность микроскопа. Но по сути и в этом примере использование интерфейса допустимо, только не предназначенного для расширения пользователем, для логического разделения ручек и реализаций.
К слову да, очевидно попытка использовать интерфейсы, предназначенные для расширения без изменения кода, в говноархитектуре, в которой любое расширение это патч, может привести к неожиданным результатам. Интерфейсы не для этого предназначены.
Только про солид говорил не он, это другой человек был.
> Прямо через Class.packageName и погнали.
А если клиент возьмёт асм и выпилит эту проверку к хуям, что будешь делать, денуво на апи поставишь?
да додики какие-то
тебе говорят сделай ручку - ты делаешь и похуй вообще че там дальше
все интеграции через rest и json
Про солид не я говорил, но в любом случае. По делу есть что сказать?
>>2993273
> при чем здесь интерфейс?
Это вариант анона выше. Я предложил использовать финальные классы.
> не предназначенного для расширения пользователем
И как бы ты ему запретил его имплементировать (если я правильно понял твою мысль)?
>>2993279
Ты случайно не Андроид разработчик? Мы сейчас ищем за 50-60 к евро, если интересно, то могу твоё резюме кинуть чару, так как твои комментарии пока самые разумные в этом треде.
>>2993281
Вот не поверишь, но такое бывает. Юзер угарает по рефлексии, меняет значения переменных API через нее, а при новом обновлении приходит с саппортным тикетом на тему: а пачему вы приватную переменную удалили!? Вы псы позорные, верните, у меня код не работает!".
Думаешь мы его нахуй посылаем? Нет. Мы спрашиваем почему ему понадобилось это делать, в чем проблема с текущим API, что ему не хватает в нем. И в следующем релизе расширяем функциональность API под этот сценарий, чтобы юзеру не нужно было лезть куда не надо.
Иногда правда посылаем нахуй если с той стороны совсем неадекваты сидят.
В общем, лучше всего не верить, что пользователь прочтет документацию и не имплементирует интерфейс который он не должен имплементировать. Лучше на уровне рантайма валить API если задекчена пользовательская имплементации с сообщением, что интерфейс хоть и публичный, но трогать его нельзя.
До какой степени доходить в подобном битьё рук юзера это решается командой.
> И как бы ты ему запретил его имплементировать (если я правильно понял твою мысль)?
В документации прописал, что этот интерфейс не надо реализовывать. Вопрос соблюдения этого это скорее вопрос средств анализа кода, чем подхода, в идеале иметь какую-нибудь аннотацию. В новых версиях джавы как раз подобное и добавили, называется силед интерфейсы.
Но вообще я подумал над этой темой, т.к. буквально сегодня работал над небольшим апи, что вероятно потребует расширения, и которое поставляется через интерфейс. Тут проблема идёт не от интерфейсов. Если есть необходимость в полиморфизме для непостоянного апи, придётся бороться с проблемами брекинг ченджей. Интерфейс тут лишь как подход, и он даже удобен в контексте этой проблемы, так как есть такая штука как дефолтные методы, а добавленные новые методы в интерфейс даже без дефолтной реализации не являются де-факто поломкой обратной совместимости, так как уже скомпилированный код продолжит работать, и не происходит такой ситуации что тому кому не нужны новые методы интерфейса приходиться их реализовывать. Финальный класс не решает проблему, а просто запихивает говно под ковёр, запрещая полиморфизм. Если пользователю понадобится полиморфизм, ему придётся переделывать весь свой код на использование своего собственного интерфейса над обёрткой этого класса. А если появится задача, которая может быть решена с помощью полиморфизма без изменения апи, то в лучшем случае придётся ждать до нового релиза этого апи. Отсюда кстати и появляются залазящие в приватные переменные пользователи, потому что апи нерасширяемо без изменения кода.
> Sealed interfaces
Вот зачем они нужны. Я их как-то мимо обходил всё время, зря.
> дефолтные методы в интерфейсе
Антипаттерн. Интерфейс на то и интерфейс, что не должен содержать в себе имплементацию.
> скомпилированный код продолжит работать, значит не ломаем обратную совместимость
Я определяю поломку обратной совместимости как необходимость внесения изменений в клиент при обновлении на новую минорную версию API.
Добавление метода интерфейса на стороне API вполне требует от пользователя менять код клиента.
> финальный класс не решает проблему
Решает, я уже выше много раз объяснил как.
> Если пользователю понадобиться полиморфизм
Пользователю клиента нужен метод, который решал бы его проблему, а заниматься добавлением нового функционала в API посредством реализации интерфейсов.
> при нерасширяемо без изменения кода
Есть Client API, а есть API Provider (SPI) https://en.m.wikipedia.org/wiki/Service_provider_interface
Это два разных API. У них разные задачи. Если планируется использовать пользовательские имплементации функционала, то пишешь SPI, если планируется, что пользователь вызывает твой функционал, то это Client API. Если их смешивать в одном API, то получается та самая "правильная архитектура", которая ни туда ни сюда.
Тебе лишь бы высрать в ответ что-то, или что? Ни одного слова по делу.
> Антипаттерн.
Потому что тыскозал?
> Я определяю поломку обратной совместимости как необходимость внесения изменений в клиент при обновлении на новую минорную версию API.
Ну мало ли что ты там определяешь. Тащи фактические проблемы от этого. Необходимость нажать одну кнопку это не проблема.
>Решает, я уже выше много раз объяснил как.
А я тебе ответил, что не решает.
> Есть Client API, а есть API Provider (SPI) https://en.m.wikipedia.org/wiki/Service_provider_interface
> Это два разных API. У них разные задачи.
И что? Какое это отношение к тому что ты процитировал имеет?
>>2993547
> Потому что ты сказал?
Потому что добавление дефолтных методов в интерфейс превращает его по сути в абстрактный класс.
Дефолтные методы были добавлены исключительно для того сценария который ты описал. Когда разработчику нужно добавить метод в интерфейс, но при этом он не хочет ломать обратную совместимость.
Знаешь как ещё можно было решить эту проблему? Не использовать интерфейс для API, который должен быть способен расширять свою функционалость от версии к версии.
> тащи проблемы от этого
Если для тебя невозможность собрать клиент после обновления библиотеки это не проблема, то навряд ли я смогу тебя в чем-то убедить.
> я тебе ответил, что не решает
И в чём твои аргументы были? Я прочитал твои сообщения и их нет, кроме "говно под ковер".
> какое это имеет отношение к процитированному
То что мы говорим про API, а ты сказал про SPI, но видимо даже не понял этого.
> Потому что добавление дефолтных методов в интерфейс превращает его по сути в абстрактный класс.
А проблема-то в чём?
> Если для тебя невозможность собрать клиент после обновления библиотеки это не проблема, то навряд ли я смогу тебя в чем-то убедить.
Слив принят.
> И в чём твои аргументы были? Я прочитал твои сообщения и их нет, кроме "говно под ковер".
>Но вообще я подумал над этой темой, т.к. буквально сегодня работал над небольшим апи, что вероятно потребует расширения, и которое поставляется через интерфейс. Тут проблема идёт не от интерфейсов. Если есть необходимость в полиморфизме для непостоянного апи, придётся бороться с проблемами брекинг ченджей. Интерфейс тут лишь как подход, и он даже удобен в контексте этой проблемы, так как есть такая штука как дефолтные методы, а добавленные новые методы в интерфейс даже без дефолтной реализации не являются де-факто поломкой обратной совместимости, так как уже скомпилированный код продолжит работать, и не происходит такой ситуации что тому кому не нужны новые методы интерфейса приходиться их реализовывать. Финальный класс не решает проблему, а просто запихивает говно под ковёр, запрещая полиморфизм. Если пользователю понадобится полиморфизм, ему придётся переделывать весь свой код на использование своего собственного интерфейса над обёрткой этого класса. А если появится задача, которая может быть решена с помощью полиморфизма без изменения апи, то в лучшем случае придётся ждать до нового релиза этого апи. Отсюда кстати и появляются залазящие в приватные переменные пользователи, потому что апи нерасширяемо без изменения кода.
> То что мы говорим про API, а ты сказал про SPI, но видимо даже не понял этого.
>И что? Какое это отношение к тому что ты процитировал имеет?
Не ворочайся, слитое.
>Не использовать интерфейс для API, который должен быть способен расширять свою функционалость от версии к версии.
т.е. не использовать интерфейсы никогда.
Можно их использовать, просто нужно отделить API от SPI. Можно прямо на уровне пакетов
net.sosach.api
net.sosach.spi
В API содержать финальные классы, готовые к расширению функциональности в любой момент. А в SPI держать интерфейсы, которые могут быть имплементированы пользователем.
SPI интерфейсы могут быть использованы как внешний объект для API. Заметь, мы не возвращаем этот интерфейс из API пользователю, мы принимаем его как внешнюю сущность.
Например, метод у финального класса типа setFormatter(Formatter formattet);, где formatter это интерфейс, который лежит в SPI.
Такой форматтер будет иметь минимальное количество методов (в идеале один) и мы будем гарантировать пользователю, что этот интерфейс никогда не изменится.
В этом случае использование интерфейсов безопасно, наш API может зависеть от интерфейсов, но не полагается на конкретную их имплементацию. Мы сохранили способность API расширятся за счёт использования финальных классов и мы дали возможность пользователю расширять функционал API через SPI.
Ахуительная теория бро. А теперь расскажи как ты реализуешь JDBC API по этой парадигме? Как будут выглядеть классы для sql типов типа blob/clob? Как добавить новый метод?
Ну как выглядит типичный JDBC хеловорлд: из DriverManager делаем openConnection() и получаем Connection. Дальше prepareStatement() и получаем PreparedStatement, из него получаем ResultSet, из него Blob, а там уже всякие readXxx(). И как это всё будет работать когда JDBC API обновиться, а драйвер нет.
Сейчас обновляю путом со всеми полями. Ну или дтошкой с почти всеми полями.
Ну то есть фронт читает гетом все поля, что ему доступны, меняет те, что поменял пользователь, а какие не поменял - передает без изменения. И я обычно все без каких-то проверок, кроме валидаций апдейчу в бд.
Ну или иногда там что-то есть в дто, но обновлять это в некоторых случаях нельзя. Ну и тогда или игнорирую поле или эксепшон выкидываю.
Но мне кажется это тупо, особенно если в дто 30-50 полей, а измениться может только одно или два. Гонять туда-сюда лишние сотни килобайт не ясно зачем. Особенно если некоторые поля могут быть побольше. Не огромные, но пару тысяч знаков.
Но патчем это надо по одному полю передавать? 50 эндпоинтов это тупо.
На первой ссылке в гугле нашел вот такую статью на баелдунге:
https://www.baeldung.com/spring-rest-json-patch
У этого подхода есть даже стандарт:
https://datatracker.ietf.org/doc/html/rfc6901
И свой Content-Type: application/json-patch+json
Выглядит неплохо:
- Получаем список операций. Меня интересует replace. Ну и remove, чтобы занулять поля, потому что вроде бы в replace null запрещены. Список операций лежит в JsonPatch
- Достаем сущность по ид
- Через apply делаем мердж нужных полей с нужными операциями.
- Полностью сохраняем сущность в бд.
Но вот вопросы:
1. Реально ли таким подходом пользуются? На гитхабе у библиотеки https://github.com/java-json-tools/json-patch всего 700 звездочек и <groupId>com.github.java-json-tools</groupId> какой-то васянский.
2. Норм все будет с валидациями? У меня на 50 полей 40 валидаций раскидано, чисто с содержимым связаны, не просто ненулевое. Ну вот допустим они будут применяться во время apply. И так же все схватится адвайсами и выкинется правильная ошибка. Но валидации они не на сущности, а на дтошки, потому что в разных эндпоинтах валидации могут быть разные. Это получается нужно мапииь сущность в дтошку и уже ее мерджить и потом обратьно мапить?
3. В бд все сохраняется все равно скопом. И нужно делать предзапрос с селектом по ид. Чтобы сделать upate запрос с произвольным количеством полей через jdbc эта библиотека не подойдет, придется самому что-то похожее на список ReplaceOperation городить. Самому валидировать есть ли все пришедшие поля, самому доставать валидации на поля, а потом уже строить запрос.
Сейчас обновляю путом со всеми полями. Ну или дтошкой с почти всеми полями.
Ну то есть фронт читает гетом все поля, что ему доступны, меняет те, что поменял пользователь, а какие не поменял - передает без изменения. И я обычно все без каких-то проверок, кроме валидаций апдейчу в бд.
Ну или иногда там что-то есть в дто, но обновлять это в некоторых случаях нельзя. Ну и тогда или игнорирую поле или эксепшон выкидываю.
Но мне кажется это тупо, особенно если в дто 30-50 полей, а измениться может только одно или два. Гонять туда-сюда лишние сотни килобайт не ясно зачем. Особенно если некоторые поля могут быть побольше. Не огромные, но пару тысяч знаков.
Но патчем это надо по одному полю передавать? 50 эндпоинтов это тупо.
На первой ссылке в гугле нашел вот такую статью на баелдунге:
https://www.baeldung.com/spring-rest-json-patch
У этого подхода есть даже стандарт:
https://datatracker.ietf.org/doc/html/rfc6901
И свой Content-Type: application/json-patch+json
Выглядит неплохо:
- Получаем список операций. Меня интересует replace. Ну и remove, чтобы занулять поля, потому что вроде бы в replace null запрещены. Список операций лежит в JsonPatch
- Достаем сущность по ид
- Через apply делаем мердж нужных полей с нужными операциями.
- Полностью сохраняем сущность в бд.
Но вот вопросы:
1. Реально ли таким подходом пользуются? На гитхабе у библиотеки https://github.com/java-json-tools/json-patch всего 700 звездочек и <groupId>com.github.java-json-tools</groupId> какой-то васянский.
2. Норм все будет с валидациями? У меня на 50 полей 40 валидаций раскидано, чисто с содержимым связаны, не просто ненулевое. Ну вот допустим они будут применяться во время apply. И так же все схватится адвайсами и выкинется правильная ошибка. Но валидации они не на сущности, а на дтошки, потому что в разных эндпоинтах валидации могут быть разные. Это получается нужно мапииь сущность в дтошку и уже ее мерджить и потом обратьно мапить?
3. В бд все сохраняется все равно скопом. И нужно делать предзапрос с селектом по ид. Чтобы сделать upate запрос с произвольным количеством полей через jdbc эта библиотека не подойдет, придется самому что-то похожее на список ReplaceOperation городить. Самому валидировать есть ли все пришедшие поля, самому доставать валидации на поля, а потом уже строить запрос.
>отделить апи от спи
Как же напыщенные анальники любят придумывать какую-то хуйню и выдавать это за законы вселенной, пиздец просто.
Тебе, оболдую, уже сто раз сказали, что такое будет работать до тех пор, пока не понадобиться расширение финального класса пользователем. Каноничный пример это апи, объединяющее несколько платформ. Но разве долбоёб, строящий архитектуру на финальных классах и потом жалующийся, что пользователи закономерно лезут внутрь его нерасширяемого кала пытаясь выполнить нормальные задачи поймёт?
Кококо н+1, так это решаемо и в хибере, в крайнем случае есть нейтив и jdbc, который и так у всех под капотом.
Кококо динамические запросы, ну используй критериа апи, та же громозкая хуета с запросом в пол экрана.
Кококо генерит сам классы, модель, и чо и нахуя, вы еще xsd везде используйте и им классы генерьте.
Так нахуя, а главное зачем? это важно, я не знаю стоит ли изучать этот кал или изучу что-нибудь полезнее
Мы используем жук, чтобы не ебаться с персистент контекстом и жизненным циклом энтити и горой костылей, которую порождает эта хуйня.
В 3 из 15 сервисах спринг дата. Там самые простые методы в репо. И все равно периодически в ногу стреляет.
Плюс сильная типизация во всякой хуйне, типа оконных функций, сте, базозависимых функций(постгреса). Хорошая поддержка и маппинг юдт, джейсонов и массивов.
>Таб комплиты в идее
так это есть в @Query "" не? Ну и это такое себе, вон хибернейт есть и спринг дата
>Типобезопасность
А в чем проблема передавать в сукили параметры определенных типов :param?
Переход с базы на базу это очень редкий кейс.
Если баз несколько, просто используешь несколько датасорцов с несколькими диалектами.
Хибер отвязывается от реализации через запрет использования оригинальных фич конкретной бд, которые иногда очень удобны.
> Ну и это такое себе, вон хибернейт есть и спринг дата
А причём тут спринг дата? Речь шла про сравнение с скл. У спринг даты другие проблемы.
>>2994614
Только одна библиотека в мире может сжирать различия между бд или что?
>>2994616
> Переход с базы на базу это очень редкий кейс.
Ну это и не основополагающее преимущество жука. Просто как приятный бонус.
>чтобы не ебаться с персистент контекстом и жизненным циклом энтити и горой костылей, которую порождает эта хуйня
подробнее, вы работаете напрямую с EntityManager и все руками?
>самые простые методы в репо. И все равно периодически в ногу стреляет.
пример? я знаю только при oneToOne с его не lazy
Что жук, что хибернет кал ебучий. Выбор стоит между кверидсл и ормлайт.
Нет, не напрямую.
Да там миллион этого говна. Тот же метод сейв спринг даты сиди и вспоминай в каких случаях какую сикулю генерит.
И кеш этот ебучий тоже в ногу стреляет если пользоваться и спринг датой и нативными кверями.
Еще с каскадированием и с генерацией были проблемы.
Про проблемы и костыли хибера есть отдельные сайты, им посвящены сотни докладов и десятки тысяч вопросов на стековерфлоу.
Видел я и критерию - очень уебищное апи. Неудобное и много не может.
хуита. Лучше делать интеграционные тесты на все запросы и запросы писать текстом
>так это есть в @Query "" не?
там очень ограниченный функционал. И зачем использовать ограниченный функционал, но писать те же самые запросы?
"типобезопасность" защищает только от грамматических ошибок, не от неправильного запроса. Значит полюбому надо писать тест чтобы этот запрос гонялся в базу.
А если есть такой тест, то "типобезопасность" не нужна. Он упадёт на грамматической ошибке
причём тут хибер. Достаточно лёгкой либы чтобы делала все эти коннекшены, prepared statements и пулы потоков. А запросы писать руками. Но при этом нужны тесты с поднятием и раскатыванием базы
Если запрос сложный, то ты заебешься писать кучу тестов на один запрос, половину из которых можно было бы просто типобезопасностью решить.
Ну и жук и есть достаточно легкая либа, если использовать кор только, то будет именно так как ты сказал?
> если использовать кор только, то будет именно так как ты сказал?
наверно да
> половину из которых можно было бы просто типобезопасностью решить
нифига, если сложный запрос то тем более надо его тестировать. Мне самому стрёмно и страшно отдавать что-то в прод, ниразу не запустив запрос
И что, банить людей за тупость?
Я всю апишку тестирую, где штук 5 запросов выполняется, пару из которых могут быть сложными. Ну и преобразование данных между запросами может тоже быть не совсем уж тривиальным.
Если все по отдельности тестировать, да еще и на тесты спихивать то, что можно было бы спихнуть на типы, то на один эндпоинт с маломальской логикой мне вместо 5-10 тестов пришлось бы писать 100.
Нахуя ты доказываешь что-то этому школьнику?
бамп длиннопосту
если апишка дёргает этот запрос - то норм. На то он и называется интеграционным
filter|query={...json or some expression}Но это уже оптимизировал в случае придётся перетаскивать код в этом примере инкапсуляции.
Это копия, сохраненная 30 марта в 15:02.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.