Прочитайте код и подсчитайте ошибки

В представленном коде можно выделить несколько ошибок и проблем:

Короткий ответ

Что ответить на собеседовании

В представленном коде можно выделить несколько ошибок и проблем:

Подробный разбор

Ответ с пояснениями

Условие

Прочитайте код и подсчитайте ошибки

@Component
public class AuthorSearchService {

    @Autowired
    private AuthorRepository authorRepository;
    @Autowired
    private StatisticsRepository statisticsRepository;

    private AlertRestClient arc = new AlertRestClient();

    // В query может быть как полностью ввд, так и часть имени, например "Вадим Павло" или "павло"
    @Transactional
    public List<Author> search(String query) {
        List<Author> authors = authorRepository.findByNameContainingIgnoreCase(query);
        Statistics s = statisticsRepository.findById(query).orElse(null);
        if (s == null) s = new Statistics(query);
        s.setNumbers(s.getNumbers() + 1);
        statisticsRepository.save(s);
        if (s.getNumbers() > 1000 && authors.size() > 1000) {
            System.out.println("too popular search with too much data, sending an alert...");
            arc.send(query, s.getNumbers(), authors.size());
        }

        return authors;
    }
}

@Entity
@Data
public class Author {
    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "author")
    private List<Book> books;

    public Author(String name) {
        this.name = name;
    }
}

Ответ

В представленном коде можно выделить несколько ошибок и проблем:

  1. Отсутствие конструктора без параметров в классе Author

    • В JPA сущности должен быть публичный или защищённый конструктор без параметров. В коде есть только конструктор с параметром name.
  2. Инициализация AlertRestClient вне Spring-контекста

    • AlertRestClient arc = new AlertRestClient(); создаётся вручную, а не через DI. Лучше внедрять через @Autowired или конструктор, чтобы использовать преимущества Spring (например, конфигурацию, мокирование).
  3. Потенциальная проблема с транзакцией и чтением/записью статистики

    • Метод помечен @Transactional, что хорошо, но если statisticsRepository.findById(query) возвращает null, создаётся новый объект Statistics(query), возможно, без корректной инициализации ID.
  4. Использование query как ID для Statistics

    • Если Statistics использует query как идентификатор, это должно быть явно указано в сущности. Иначе findById(query) может не работать.
  5. Отсутствие обработки исключений при отправке алерта

    • Вызов arc.send(...) может выбросить исключение, которое не обрабатывается.
  6. Потенциальная проблема с производительностью при больших данных

    • Если authors.size() очень большой, загрузка всех авторов в память может быть неэффективной.
  7. Отсутствие логгера

    • Используется System.out.println, лучше использовать логгер.
  8. Отсутствие аннотации @NoArgsConstructor или явного конструктора без параметров в Author

Пример исправления конструктора Author:

@Entity
@Data
@NoArgsConstructor
public class Author {
    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "author")
    private List<Book> books;

    public Author(String name) {
        this.name = name;
    }
}

И пример внедрения AlertRestClient через DI:

@Component
public class AuthorSearchService {

    @Autowired
    private AuthorRepository authorRepository;
    @Autowired
    private StatisticsRepository statisticsRepository;
    @Autowired
    private AlertRestClient arc;

    @Transactional
    public List<Author> search(String query) {
        // ...
    }
}

В целом, код требует доработки для корректной работы с JPA и Spring.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее