• С чего начать разработку своего приложения?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    1. Научиться получать данные с внешнего ресурса (те самые таблицы) и выводить их в консоль как есть.
    2. Разобраться что за данные ты получаешь. JSON? XML? Научиться парсить (разбирать) их на отдельные поля и сохранять в коллекцию. И выводить в консоль.
    3. Подключить базу данных и сохранять уже в базу, а не в коллекцию.
    4. Подключить web. У Шилдта наверно есть про сервлеты. Вот на них можно. Цель - выводить данные уже не в консоль, а в браузер - в виде JSON.
    5. Оставить это как версию и сделать то же самое на Spring Boot. Работодателям нужен только Spring, но то что ты делал на "низком уровне" тоже может пригодиться, типа "Я и так тоже могу".
    6. Теперь думать про фронт. В любом случае, надо знать основы HTML, CSS, вёрстки. Вариантов несколько:
    - интегрировать фронт прямо в Spring-приложение, используя шаблонизаторы (их "из коробки" 3 на выбор, самый популярный thymeleaf);
    - сделать фронт как отдельное приложение для браузера, которое будет ходить на бэк за данными и взаимодействовать с пользователем. Самый популярный фреймворк для фронта - React, но бэкэндерам лучше заходит Angular;
    - экзотика типа Vaadin.....
    7. На основе кода бэка сделать бота в Telegram и/или мобильное приложение (если интересно, конечно).
    Я бы советовал по мере эволюции бэка уже искать работу/стажировку. Новичкам часто дают тестовые задания - делая их ты лучше поймёшь что нужно работодателям, ну и потренируешься.
    Удачи!
    Ответ написан
    3 комментария
  • Какие сейчас актуальные книги для изучения java?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Книги это хорошо, но недостаточно. В книгах есть примеры кода, возможно даже много примеров. Но так как хорошие книги многократно переиздаются, то и примеры там древние. Да, в java мало что меняется, в основном добавляется новое. Но это новое добавляется не просто так, а потому что это очень надо программистам. И они это новое радостно используют в текущих проектах. Соответственно чтобы понять что они пишут надо изучать новое, а не старое :)
    А ещё в книгах нет задач (или почти нет). Программирование - практический навык, поэтому нарабатывать его надо решая задачи много задач, с автоматической проверкой решений.
    Поэтому я бы посоветовал курсы :) А книги - любые из тех что советовали выше, но только как дополнение к курсам.
    Ответ написан
  • Правильно ли я реализую абстрактный класс?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    абстрактный класс реализует базовый функционал, а классу наследнику передается лишь определенная часть функционала?

    Вроде наоборот :) Конкретный класс расширяет абстрактный, т.е. добавляет ему возможностей. Например, абстрактный Animal{} может и не уметь "говорить", поэтому метод void say(){} ему задавать не надо. И Fish extends Animal{} не будет иметь этого метода, а Dog extends Animal{} будет.
    Либо класс может уточнять абстрактный класс. Пример: Animal может иметь абстрактный метод void move();, а потомки будут обязаны его реализовать: птичка будет летать, рыбка плавать, а собачка бегать.
    Как-то так :)
    Ответ написан
    Комментировать
  • Как составить регулярное выражение?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Как вариант:
    String s = """
        ... ваш текст ...
        """;
    
    List<String> words = Arrays.stream(s.split("[ ,\\p{Punct},\n]"))
        .filter(w -> !w.isEmpty())
        .toList();
    
    System.out.println(words);
    Ответ написан
    Комментировать
  • В каком порядке изучать Java?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Начни с новичкового курса по Java Core с большим количеством задач с автопроверкой, например, javarush.com. Задачи решай сразу в IDEA, нафиг советчиков с блокнотами и эклипсами. Привыкай к профессиональному инструменту, смотри подсказки, учи шорткаты. Много задач нужно чтобы руки и глаза привыкли к синтаксису и конструкциям языка.
    Параллельно можешь взять этот курс.
    Когда плюс-минус освоишь коллекции параллельно осваивай SQL.
    Когда дойдёшь до join, параллельно начни учить Spring.
    Посмотри видео на ютупе (Евгений Сулейманов, letscode) о том как в принципе собираются простые проекты, что за чем, в какой последовательности.
    Когда процентов на 70-80 пройдёшь эти курсы начни ходить на собесы (искать стажировку можно и раньше), решай тестовые задания, выписывай что спрашивают, доучивай это.
    Удачи!
    Ответ написан
    Комментировать
  • Bootstrap прокрутка внутри столбца без прокрутки всей страницы, как?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Сам протрахался с этим пол-дня, поэтому оставлю рабочий шаблон:
    <div class="container" style="height: 100vh; border: black solid " >
      <div class="row h-100">
        <div class="col-1">
          <p>MENU</p>
          <p>MENU</p>
          <p>MENU</p>
        </div>
        <div class="col-3 h-100 overflow-auto">
          <p>content</p>
          <p>content</p>
          <p>content</p>
          <p>content</p>
          <p>content</p>
          <p>content</p>
          <p>content</p>
          .......................
          <p>content</p>
          <p>content</p>
          <p>content</p>
          <p>content</p>
        </div>
      </div>
    </div>

    Когда контента становится много, появляется полоса прокрутки. Высоту контейнера надо задавать в vh - это попугаи, аналогичные процентам (проценты почему-то не работают).
    Ответ написан
    Комментировать
  • Angular, Bootstrap, datePicker, как подставить текущую дату?

    @Wan-Derer Автор вопроса
    Зобанели на Хабре, волки́ ;((
    Кому интересно: провёл небольшое исследование и был зело фраппирован!
    Сделал кнопочку, которая делает
    console.log('----------> ', typeof this.criteria.to, this.criteria.to);

    Так вот: если её нажать до выбора даты пикером (т.е. когда поле только инициализировано), типом поля является object, а если сначала выбрать, а потом нажать - уже string! И ладно что пикеры выдают string (хотя как ладно, мне ещё предстоит валидация полей: чую будет гимор), так ещё и TypeScript меняет тип переменной, хотя в интерфейсе чётко задано: Date. Как так-то?!
    Что касается подстановки текущей даты, то меняем тип поля на string и инициализируем, например, так:
    ...........
    to: new Date().toISOString().split('T')[0],
    ...........

    и, вроде, всё работает (со строкой, понятно).
    Кто знает способы получше - напишите, пожалуйста.
    Ответ написан
    Комментировать
  • Какое оптимальное время въехать в проект?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Если ты хорошо представляешь себе сложность проекта, распиши для себя: на это мне надо 2 часа, на это час..... ну и на "туда-сюда" ещё примерно столько. Это может показаться ерундой, "ну как я могу оценить?", но ты удивишься насколько точной окажется в итоге эта приблизительная оценка.
    После этого смело иди к заказчику и говори: "На эту работу мне надо приблизительно N дней (при условии что там всё стандартно и не выплывет никакой жопы)". А дальше - их право соглашаться или нет.
    Договор - вещь взаимная. Они предлагают свои условия, ты - свои. На чём сойдётесь - так и работайте. А соглашаться на заведомо неисполнимые условия фрилансеру, конечно, не надо.
    Ответ написан
  • Договорился на подработку, прислали договор на подписание, в нём увидел пункты которые не видел в других подобных договорах - это мошенники?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Мне кажется, если в договоре хоть что-то не устраивает, надо (на выбор):
    - предлагать свой вариант;
    - просто сваливать;
    - просить аванс в таком размере, который тебя устроит как плата за всю работу, т.е. если остаток тебе не заплатят.
    Ответ написан
    Комментировать
  • Бывают ли вакансии на frontend без лайвкодинга и тестовых работ?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    А зачем? По-моему, лайвкодить это хорошо и весело. Заодно можно и языком потрещать на всякие рабочие и нерабочие темы :) Только кодить, конечно, надо в привычной IDE и не сортировки деревьев :)
    А тестовое - это тоже хорошо. Конечно, такое, которое можно сделать за день. Попадётся интересное - себе же в порфолио и положишь :)
    Ответ написан
    5 комментариев
  • Как сложить содержимое одного int между собой?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Могу предположить что model это экземпляр товара. Тогда все товары хранятся в какой-то коллекции, например,
    List<Model> list = ..............
    Тогда сумма будет считаться примерно так:
    int total = list.stream()
          .mapToInt(model -> Integer.parseInt(model.getPrice())*Integer.parseInt(model.getTovarValue()))
          .sum();
    Ответ написан
    Комментировать
  • Как сделать фильтр в виде checkbox`ов на сайте Spring?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Можно использовать RequestParam - параметры адресной строки. Они могут быть разных типов. Пример из моего проекта:
    @GetMapping("/list")
      List<AuditAssetItem> getChangesByCriteria(
        @RequestParam int assetid,
        @RequestParam String from,
        @RequestParam String to,
        @RequestParam boolean item,
        @RequestParam boolean rights,
        @RequestParam boolean extended
      ) {
    
        return service.getAuditListByCriteria(assetid, from, to, item, rights, extended);
      }

    В строке браузера адрес будет выглядеть примерно так:
    http : //mysite.ru/list?assetid=123&from=2020-12-01&to=2020-12-10&item=true&rights=true&extended=false

    Spring разложит эти параметры по переменным в соответствии с их типами, далее ты засылаешь их в сервис и там по своей логике корректируешь запрос или пишешь несколько запросов.
    Ответ написан
  • Spring boot: как логировать в файл отдельно от консоли?

    @Wan-Derer Автор вопроса
    Зобанели на Хабре, волки́ ;((
    Тэкс! На случай если кому интересно (и себе для памяти).
    В папку resources надо добавить файл logback-spring.xml
    <?xml version="1.0" encoding="UTF-8"?>
    
    <configuration>
      <!--https://docs.spring.io/spring-boot/docs/2.7.6/reference/html/features.html#features.logging-->
      <!--https://docs.spring.io/spring-boot/docs/2.7.6/reference/html/howto.html#howto.logging-->
      <!--https://www.baeldung.com/spring-boot-logging-->
      <!--https://github.com/spring-projects/spring-boot/blob/v2.7.6/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/-->
    
      <include resource="org/springframework/boot/logging/logback/defaults.xml" />
      <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    
      <property name="LOG" value="log-folder"/>
    
      <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
          <Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %logger : %m%n</Pattern>
          <charset>${FILE_LOG_CHARSET}</charset>
        </encoder>
    
        <file>${LOG}/my-log-file.log</file>
    
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
          <fileNamePattern>${LOG}/archived/my-log-file-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
          <cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
          <maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
          <totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
          <maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-7}</maxHistory>
        </rollingPolicy>
      </appender>
    
      <root level="info">
        <appender-ref ref="CONSOLE"/>
      </root>
    
      <logger name="my-logger-name" level="info">
        <appender-ref ref="ROLLING_FILE"/>
      </logger>
    
    </configuration>


    Там закомментированы ссылки на статьи, которыми пользовался для решения.

    Логгер в классе определяется так:

    static final Logger log = LoggerFactory.getLogger("my-logger-name");
    Ответ написан
    Комментировать
  • Какой инструмент-конструктор выбрать для разработки UI для REST API?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Я тоже бэк :) Когда возник вопрос "для себя" делать простой фронт, попытался изучать React как самый популярный. Но чёт не осилил, какой-то он предельно странный. А вот Angular зашёл! Много слышал что он очень сложный, но я особых сложностей не узрел, по крайней мере для моих примитивных задач. Говорят, Angular заходит именно бэкам т.к. у нас нет проблем с основами ООП.
    Я думаю что фронт лучше делать именно на фронтовых фреймворках чем на Java-шаблонизаторах (таймлиф, мусташ и пр.). Во-первых, их (шаблонизаторов) несколько и непонятно какой учить. А на фронте 3 фреймворка и все популярны. Потом - ты получаешь ещё одну специальность, пусть и на примитивном уровне. Далее - тренируясь с "настоящим" фронтом, ты начинаешь лучше понимать что нужно фронту и, соответственно, лучше пишешь бэк.
    Я учил Angular по курсу Владилена Минина. Правда, он довольно старый (по 8-9 версии, а сейчас актуальна 14), но в целом актуальный. Плюс и минус этого курса - автор объясняет не "академично", а исключительно на примерах. Минус - тяжело потом что-то искать в официальных доках Ангуляра, просто не знаешь как формулировать запрос. Плюс - зная как должен выглядеть твой фронт, ты практически сразу начинаешь его писать (конечно, самые основы HTML/CSS знать надо).
    Удобно писать и отлаживать бэк и фронт отдельно. А запускать фронт "на проде" можно как на отдельном сервере (Nginx, Apache), так и "заэмбедить" в Jar-файл и тогда он будет работать на "встроенном" сервере (Tomcat, Netty).
    ЗЫ: да, учил "для себя", но активно использую по работе :))
    Ответ написан
    Комментировать
  • Как можно практически закрепить знания JAVA SE?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Вот :)
    Ответ написан
    Комментировать
  • Как закрепить пробелы в знаниях по Java?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Если хорошо знаешь коллекции, можешь приступать у Spring. А ещё учи SQL. А ещё Stream API. Ну и многопоточку, хотя бы на уровне понимания.
    Я бы не советовал "выучить всю Java" до уровня сдачи экзамена у Oracle и только потом приступать к фреймворкам. Надо так:
    база -> вширь -> влубь -> вширь -> вглубь -> вспомнил что забыл -> вширь...
    С SQL так: учишь основу, потом соединяешь с Java (делаешь простые примеры на JDBC), потом делаешь примеры на Hibernate, потом соединяешь всё в Spring. Делая проекты на Spring ты чаще всего будешь использовать Spring Data JPA (по сути Hibernate), но имея перед собой свои же примеры ты легко напишешь хитрый метод, который эффективно вытащит данные через JDBC. Или будет маленький проектик без Spring. Или в консоли полазать с ручными запросами. Но опять же, не стоит учить "весь SQL полностью". Хорошо понял JOIN - можешь приступать к Hibernate и Spring Data JPA. Потом будешь добирать чего не хватает, тебе будет легче т.к. имея опыт, ты будешь понимать что спрашивать у Яндекса и не будешь падать в обморок от вида кода на StackOverFlow :)
    Ответ написан
    Комментировать
  • Какую область программирования выбрать PHP или Java?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Надо попробовать то и другое и выбрать то что прёт :) Про ПЫХП не скажу, но по Java есть нюансы:
    1. Java сложная. Надо учить и сам язык, и подходы к разработке/архитектуру, и фреймворки (на чистой Java мало кто пишет), и сопутствующие вещи типа SQL, MQ и т,п, Я бы сказал, имея твой опыт, надо закладываться на пол-года ежедневной учёбы минимум, а может и на год.
    2. Стажировок по Java нет. Точнее есть, но они для студентов. Попасть туда свитчеру нереально, по кр. мере у меня не получилось.
    Ответ написан
    3 комментария
  • Как хранить статическую информацию в spring-приложении?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Ну, для хранения данных есть два "контейнера": файл или база данных.
    Для файла можно выбрать формат JSON: и человекочитаемо, и легко парсить, и нет проблем с русским языком (в отл от .properties).
    Ну а база - любая база. Если концепция вопросов-ответов укладывается в "ключ-значение", то можно брать что-то NO-SQL (Redis и пр.).
    Но мне кажется что JSON - самое простое, и главное - не нужен программист для правки данных.
    Ответ написан
    Комментировать
  • Как правильно отправлять файлы в RESTfull приложении?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Можно разделить Java-объект на два и на фронте получать двумя разными запросами:
    - описание: объект -> DTO-объект (тот же объект, но без картинки) -> JSON;
    - картинка: массив -> поток -> MIME-тип картинка.
    Это имеет смысл если картинка довольно большая, если только миниатюра, то можно передавать всё вместе.
    Ответ написан
    Комментировать
  • Как правильно сделать имплементацию в джава компаратору с помощью лямбды?

    @Wan-Derer
    Зобанели на Хабре, волки́ ;((
    Да, со скобочками ты навертел :)
    Думаю, имелось в виду что-то такое:

    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.ToString;
    
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
    
        List<Person> listPeople = new ArrayList<>();
        listPeople.add(new Person("Mari", "Ke ri", 22));
        listPeople.add(new Person("Poti", "Ty Re Mi", 18));
        listPeople.add(new Person("Pow", "Keri", 19));
        System.out.println(listPeople);
    
        // Можно так
        listPeople.sort(new PersonComparator());
    
        // А можно так
        listPeople.sort((p1, p2) -> {
          int len1 = p1.getSurname().split(" ").length;
          int len2 = p2.getSurname().split(" ").length;
          if (len1 != len2) {
            return Integer.compare(len1, len2);
          }
          return Integer.compare(p1.getAge(), p2.getAge());
        });
    
        System.out.println(listPeople);
        
      }
      
    }
    
    
    class PersonComparator implements Comparator<Person> {
    
      @Override
      public int compare(Person p1, Person p2) {
        int len1 = p1.getSurname().split(" ").length;
        int len2 = p2.getSurname().split(" ").length;
        if (len1 != len2) {
          return Integer.compare(len1, len2);
        }
        return Integer.compare(p1.getAge(), p2.getAge());
      }
      
    }
    
    
    @AllArgsConstructor
    @Getter
    @ToString
    class Person {
      private String name;
      private String surname;
      private int age;
    }


    А можно компаратор засадить прямо в класс:
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.ToString;
    
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.List;
    
    public class Main {
      public static void main(String[] args) {
    
        List<Person2> listPeople2 = new ArrayList<>();
        listPeople2.add(new Person2("Mari", "Ke ri", 22));
        listPeople2.add(new Person2("Poti", "Ty Re Mi", 18));
        listPeople2.add(new Person2("Pow", "Keri", 19));
        System.out.println(listPeople2);
    
        // Так
        listPeople2.sort((p1,p2)-> p1.compareTo(p2));
        // То же самое
        listPeople2.sort(Person2::compareTo);
        
        System.out.println(listPeople2);
    
      }
    
    }
    
    
    @AllArgsConstructor
    @Getter
    @ToString
    class Person2 implements Comparable<Person2> {
      private String name;
      private String surname;
      private int age;
    
      @Override
      public int compareTo(Person2 p) {
        int len1 = this.surname.split(" ").length;
        int len2 = p.getSurname().split(" ").length;
        if (len1 != len2) {
          return Integer.compare(len1, len2);
        }
        return Integer.compare(this.age, p.getAge());
      }
    
    }
    Ответ написан