• Как работает рекурсия в Java?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Когда вы вызываете метод из другого метода, то вызывающий метод приостанавливается в частично завершенном состоянии. Все значения переменных вызывающей функции физически сохраняются в памяти. Метод, вызванный вызывающим его методом размещается поверх вызывающего метода и происходит все то же самое, пока соблюдается рекурсивный случай (условие, при котором метод вызывает сам себя). Когда происходит базовый случай (условие, при котором рекурсия должна быть остановлена), методы по очереди возвращают управление вызвавшему их методу, вплоть до полного завершения исходного (самого нижнего) метода.
    Ответ написан
    Комментировать
  • Как оптимизировать код Java при работе со строчками?

    @Asapin
    В свободное время ковыряюсь с Rust и Wasm
    Про кеширование
    Если у вас condition бОльшую часть времени имеет малый набор возможных значений, то кешированием в данном случае будет создание хешмапы, где ключ - condition, значение - condition + ",". Можете даже использовать какой-нибудь LRU-кеш, что бы редко используемые ключи постепенно удалялись из кеша и не занимали память.

    Но если честно, в данном случае операция condition + "," настолько незначительна по вычислительной сложности, что хоть какое-то изменение вы заметите только если у вас этот участок кода вызывается в горячем цикле и генерирует столько мусора, что паузы GC перевешивают дополнительные вычисления хеша, ветвления и добавление новых данных в кеш. Но даже в этом случае нужно профилировать, например с помощью JMH и VisualVM.

    Теперь по поводу StringBuilder.
    Сразу скажу, что у меня нет под рукой IDE для Java, что бы проверить то, что будет написано дальше, все выводы сделаны только глядя на исходный код классов String и StringBuilder. Итак, поехали:
    • Код condition + "," будет преобразован компилятором в
      new StringBuilder().append(condition).append(",").toString()
      Это сразу +2 созданных объекта: StringBuilder и новый String, который будет создан в результате вызова метода StringBuilder.toString()

    • a = a.replace("^Var1:", newString); внутри себя тоже создаёт StringBuilder, у которого потом вызывается метод toString() - еще +2 объекта

    • a = a + System.lineSeparator(); опять же будет преобразован в StringBuilder + toString()


    Итого, у вас создаётся минимум 6 объектов.

    Если переменная condition может иметь произвольное значение (т.е. операции с ней нет смысла кешировать, так как всё-равно придётся каждый раз вычислять новое значение), то можете попробовать воспользоваться методом condition.concat(String str) - будете создавать только 1 объект вместо 2. Будет ли это быстрее? Не знаю, надо профилировать.
    Далее, после входа в блок if создаём новый StringBuilder вместимостью a.length() + condition.length() + 2. Если не указать длину строки, то вместимость у StringBuilder будет либо 16 символов, либо равной длине значения в переменной a (в зависимости от того, какой конструктор будет использован). И при конкатенации с новыми строками скорее всего возникнет необходимость увеличивать размер буфера, что приведёт к дополнительному копированию массивов (создать буфер с новым размером, скопировать содержимое старого буфера в новый). Поэтому желательно сразу рассчитать правильную длину результирующей строки. В любом случае, это тоже +1 объект.
    a.replace(CharSequence target, CharSequence replacement)
    можно заменить методом
    StringBuilder.replace(int start, int end, String str)
    (придётся вручную вычислить начало и конец подстроки, которую вы хотите заменить).
    Вместо a = a + System.lineSeparator(); используйте a.append(System.lineSeparator()).
    out.append(a); приведёт к созданию еще 1 объекта - либо вы вручную вызовете a.toString(), либо этот метод будет вызван за вас в методе out.append(CharSequence seq). И скорее всего приведёт еще и к копированию массива символов внутри переменной out, если вы заранее не указали вместимость с запасом.

    Итого, 3 объекта против изначальных 6 с несколькими не сразу очевидными НО. Стоит ли усложнение кода полученной экономии? Не уверен, надо профилировать. Ну и учтите, что производительность самого StringBuilder может быть разной, в зависимости от того, как вы его используете.

    Имхо, то что вы пытаетесь сделать - это экономия на спичках, которая может помочь только если у вас по настоящему высоконагруженный сервис.
    P.S. если вы пишете библиотеку, которая потом будет использоваться другими проектам, то я всеми конечностями за, если вы решили заморочиться с оптимизацией.
    Ответ написан
    1 комментарий
  • Как оптимизировать код Java при работе со строчками?

    zagayevskiy
    @zagayevskiy Куратор тега Java
    Android developer at Yandex
    да, использовать StringBuilder
    Ответ написан
    3 комментария
  • Как положить в лист миллиард объектов?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Просто вам нужно минимум 64 гигабайта свободной оперативной памяти (если я все правильно посчитал), а по факту раза в четыре больше, так как храним не примитивы, а объекты. Посему, если владеете такой памятью, то ключи для java -Xms128G -Xmx128G
    Ответ написан
    Комментировать
  • Как положить в лист миллиард объектов?

    vabka
    @vabka
    Токсичный шарпист
    передать ключ -xmg с нужным количеством памяти.
    Для миллиарда чисел нужно порядка 8гб памяти, так что выделяйте сразу гигов 16

    UPD: Только благодаря Алексею обратил внимание, что используется Long, вместо long.
    Тогда памяти будет жраться порядка 170+ гигабайт (если я не просчитался)
    Ответ написан
    Комментировать
  • Как положить в лист миллиард объектов?

    @acwartz
    Тут должна быть ваша реклама.
    задать больший размер кучи выделяемой приложению -Xmx = 16GB например. Тогда точно хватит.
    Ответ написан
    1 комментарий
  • Белый список разрешенных веб-адресов по маске подсети?

    Diman89
    @Diman89
    Пропишите в настройках "детские/смейные" DNS, у яндекса они вроде были
    Ответ написан
    Комментировать
  • Как работает в anyDesk wake on lan?

    @dronmaxman
    VoIP Administrator
    https://support.anydesk.com/Wake-on-LAN

    Ключевая подсказка
    Requirements
    At least one more AnyDesk device in the local network must be online.


    То есть в сети есть еще устройства с anydesk и они включены и именно они отправляют пакет WakeOnLan.
    Ответ написан
    1 комментарий
  • Как организовать цепочки согласающих для согласования документа?

    cjstress
    @cjstress
    C#
    Копайте в сторону FSM паттерна. Есть состояния документа, есть нужные согласующие. Согласовали - идем в следующий стейт.
    Ответ написан
    2 комментария
  • Как организовать цепочки согласающих для согласования документа?

    inoise
    @inoise
    Solution Architect, AWS Certified, Serverless
    Давайте отделять структуру данных от бизнес-логики. Нам нужно хранить отдельно документы и отдельно список подписавших этот документ. Это 2 разные таблицы. Можем для красоты добавить третью - пользователей, но совсем не обязательно (эта таблица есть только в монолитах).

    Таблица подписей может содержать ссылки на документ, пользователя, состояние подписал (bool) и разного рода служебную информацию. Если надо то можно добавить этап подписи, обязательность (required: bool) или еще что что может потребоваться. Факт одобрения можно хранить как в документе так и в отдельной таблице (если этапов подписания несколько).

    А бизнес-логика принимает уже решение как калькулировать факт одобрения документа на основе этих данных
    Ответ написан
    Комментировать
  • Как организовать цепочки согласающих для согласования документа?

    NeiroNx
    @NeiroNx
    Программист
    Скорее всего уровни у согласующих(отражающие их подчинение) - главный не подпишет пока не подписали все промежуточные начальники.
    Согласующие одного уровня вряд ли встретятся, а если и встретятся - то порядок не будет иметь значения.
    Ответ написан
    Комментировать
  • Что не правильно в выражении Stream API?

    roswell
    @roswell
    и швец, и жнец, и на дуде игрец
    .filter(x -> x.toString().endsWith(".jpg"))
    Ответ написан
    Комментировать
  • Что не правильно в выражении Stream API?

    @Terran37
    Программист
    Попробуйте использовать toLowerCase() перед поиском расширения расширением.
    Примерно так .filter(x-> x.toLowerCase().endsWith(".jpg"))
    Ответ написан
    3 комментария
  • Как создаются изменяемые пользовательские интерфейсы на Java?

    @Terran37
    Программист
    Для JavaFX вы устанавливаете SceneBuilder и далее в нем вы создаете интерфейсы в нем. Фактически на "слой" вы перетаскиваете нужные вам элементы(кнопки, таблицы), а далее добавляете код для их обработки.
    Ответ написан
    2 комментария
  • Какой проект сделать новичку чтобы вникнуть во фронтенд и бекэнд и быть востребованым на рынке труда?

    OtshelnikFm
    @OtshelnikFm
    Обо мне расскажет yawncato.com
    Сделай интернет магазин
    Сделай портал
    Сделай CRM, CRUD
    Сделай социальную сеть
    Сделай приложение с headless wordpress
    и как только:
    освоишь rest api
    освоишь mysql
    освоишь react
    освоишь api платёжных систем
    освоишь git
    - будет что показать.
    Выучи английский - тогда будет с кем поговорить.
    Ответ написан
    Комментировать
  • Как запосить список таблиц в БД из програмного кода?

    @bestie
    Если вопрос еще актуален, то самый простой вариант - в зависимости от того, какая у вас БД, посмотреть, как через SQL выгрести список всех таблиц через запрос, а потом проитерироваться по нему:
    - например, вот как предложено здесь https://stackoverflow.com/questions/53592533/list-...
    Ответ написан
    1 комментарий
  • Как в runtime подключаться к генерируемым таблицам?

    @bestie
    Не силен в Хибере, но если верить гуглу - есть вариант использовать свой интерцептор, который будет динамически менять имя таблицы https://javaaltaf.blogspot.com/2019/01/change-tabl...
    public class CustomInterceptor extends EmptyInterceptor {
     @Override
     public String onPrepareStatement(String sql) {
      System.err.println("Before Modifying SQL =" + sql);
      sql = sql.replace("ATTENDANCE_1_2019 ", "ATTENDANCE_2_2019 ");
      System.err.println("After Modifying SQL =" + sql);
      return sql;
     }
    }


    Либо как вариант - просто переходите на PlainSQL ("SELECT * FROM :table_name") + NamedParameterJdbcTemplate -> это позволит пропихивать имя таблицы в сам запрос безо всяких проблем, но результат вам придется обрабатывать руками (RowMapper'ом).
    Ответ написан
    1 комментарий
  • Кто-нибудь интегрировал ClickHouse и Spring?

    alfss
    @alfss
    https://career.habr.com/alfss
    Комментировать
  • Кто-нибудь интегрировал ClickHouse и Spring?

    Chvalov
    @Chvalov
    Ответ написан
    Комментировать