В представленном коде есть несколько проблем:
Описание задачи: Требуется реализовать 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();
}
Ответ
В представленном коде есть несколько проблем:
- Метод getPolicies() загружает все полисы из базы, а затем фильтрация и ограничение результата происходит в памяти. Это неэффективно при большом объёме данных.
- Параметр policyLimit применяется до фильтрации, что может привести к возврату неполного или некорректного набора данных.
- 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);
}
В этом примере фильтрация и лимитирование делаются в репозитории, что позволяет эффективно работать с большими объёмами данных.