Описание задачи: Требуется реализовать REST endpoint для получения списка страховых полисов, которые принадлежат заданному клиенту и являются оплаченными. Поскольку в системе существует очень большое количество полисов, требуется предусмотреть параметр для ограничения результата.

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

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

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

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

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

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

Условие

Описание задачи: Требуется реализовать REST endpoint для получения списка страховых полисов, которые принадлежат заданному клиенту и являются оплаченными. Поскольку в системе существует очень большое количество полисов, требуется предусмотреть параметр для ограничения результата.

@RestController public class ClientController {

@Value("policy.limit")
private int policyLimit;

@Autowired
private PolicyService policyService;

@RequestMapping(path = "client/{clientId}/policies", method = RequestMethod.POST)
public Response getClientPolicies(@PathVariable("clientId") String clientId) {
    List<PolicyDTO> policies = getPolicies().stream()
        .limit(policyLimit)
        .filter(p -> p.getClientIds().contains(clientId))
        .filter(p -> p.isPaid())
        .toList();
    return new Response(policies);
}

@Transactional
private List<PolicyDTO> getPolicies() {
    return policyService.getPolicies();
}

@Data
@AllArgsConstructor
public class Response {
    private List<PolicyDTO> policies;
}

@Data
public class PolicyDTO {
    private String id;
    private String name;
    private List<String> clientId;
    private Boolean isPaid;
}

@RequiredArgsConstructor
@Component
public class PolicyService {
    private PolicyDbRepository repository;

    List<PolicyDTO> getPolicies() {
        return repository.getPolicies();
    }
}

public interface PolicyDbRepository {
    List<PolicyDTO> getPolicies();
}

Ответ

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

  1. Метод getPolicies() загружает все полисы из базы, а затем фильтрация и ограничение результата происходит в памяти. Это неэффективно при большом объёме данных.
  2. Параметр policyLimit применяется до фильтрации, что может привести к возврату неполного или некорректного набора данных.
  3. HTTP метод POST не подходит для получения данных, лучше использовать GET.

Правильный подход — реализовать фильтрацию и лимитирование на уровне запроса к базе данных, чтобы выгружать только нужные полисы.

Пример исправленного контроллера:

@RestController
@RequestMapping("/client")
public class ClientController {

    @Autowired
    private PolicyService policyService;

    @GetMapping("/{clientId}/policies")
    public ResponseEntity<List<PolicyDTO>> getClientPolicies(
            @PathVariable String clientId,
            @RequestParam(defaultValue = "10") int limit) {
        List<PolicyDTO> policies = policyService.getPaidPoliciesByClient(clientId, limit);
        return ResponseEntity.ok(policies);
    }
}

@Service
public class PolicyService {

    @Autowired
    private PolicyDbRepository repository;

    public List<PolicyDTO> getPaidPoliciesByClient(String clientId, int limit) {
        return repository.findPaidPoliciesByClient(clientId, limit);
    }
}

public interface PolicyDbRepository {
    List<PolicyDTO> findPaidPoliciesByClient(String clientId, int limit);
}

В этом примере фильтрация и лимитирование делаются в репозитории, что позволяет эффективно работать с большими объёмами данных.

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

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

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

Подробнее