← Назад к вопросам

Как выглядит процесс решения задачи

1.3 Junior🔥 131 комментариев
#Soft Skills и карьера

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Как выглядит процесс решения задачи

Мой процесс решения задачи структурирован и итеративен. Разберу на конкретном примере.

Пример задачи

Такач: "Реализовать API endpoint для добавления товара в корзину. Нужна валидация, обработка ошибок и логирование."

Процесс решения

Фаза 1: Анализ (30 минут)

1.1. Уточнение требований

Вопросы к product owner или документации:

  • Какие поля требуются? (product_id, quantity)
  • Какие ограничения? (max quantity = 999, только активные товары)
  • Какие ошибки возможны? (товара нет, нет прав доступа)
  • Есть ли лимит на размер корзины?
  • Если товар уже в корзине — заменить или увеличить кол-во?

1.2. Архитектурный анализ

Смотрю на существующие примеры:

find src -name "*CartController.java"  # Есть ли уже контроллер?
grep -r "@PostMapping" src --include="*Controller.java"  # Примеры POST endpoints
find . -path "*/api/*" -name "*.java"  # Структура API

Представлю архитектуру:

Client -> CartController -> CartService -> CartRepository -> Database

1.3. Проверка существующего кода

// Есть ли уже CartService?
@Service
public class CartService {
    public void addToCart(Long userId, Long productId, int quantity) {
        // ...
    }
}

// Есть ли уже Entity?
@Entity
public class Cart {
    private Long id;
    private User user;
    private List<CartItem> items;
}

1.4. Дизайн API

POST /api/v1/carts/items
{
    "productId": 123,
    "quantity": 2
}

Ответ:
200 OK
{
    "cartId": "uuid",
    "items": [
        {"productId": 123, "quantity": 2, "price": 99.99}
    ],
    "total": 199.98
}

Ошибки:
400 Bad Request — validation error
401 Unauthorized — не авторизован
404 Not Found — товара нет
409 Conflict — товар недоступен

Фаза 2: Проектирование (30 минут)

2.1. TDD — напишу тесты сначала

@SpringBootTest
public class CartServiceTest {
    @Test
    void shouldAddProductToCart() {
        // Arrange
        User user = createUser();
        Product product = createProduct(100.0);
        
        // Act
        cartService.addToCart(user.getId(), product.getId(), 2);
        
        // Assert
        Cart cart = cartRepository.findByUserId(user.getId());
        assertEquals(1, cart.getItems().size());
        assertEquals(2, cart.getItems().get(0).getQuantity());
    }
    
    @Test
    void shouldThrowException_whenProductNotFound() {
        User user = createUser();
        
        assertThrows(ProductNotFoundException.class, () -> {
            cartService.addToCart(user.getId(), 999L, 1);
        });
    }
    
    @Test
    void shouldIncreaseQuantity_whenProductAlreadyInCart() {
        User user = createUser();
        Product product = createProduct();
        
        cartService.addToCart(user.getId(), product.getId(), 2);
        cartService.addToCart(user.getId(), product.getId(), 3);
        
        Cart cart = cartRepository.findByUserId(user.getId());
        assertEquals(1, cart.getItems().size());
        assertEquals(5, cart.getItems().get(0).getQuantity());
    }
}

2.2. Спроектирую классы

// DTO для входящего запроса
public class AddToCartRequest {
    @NotNull(message = "Product ID required")
    private Long productId;
    
    @Min(1)
    @Max(999)
    private int quantity;
}

// DTO для ответа
public class CartResponse {
    private String cartId;
    private List<CartItemResponse> items;
    private BigDecimal total;
}

// Exception
public class ProductNotFoundException extends RuntimeException {
    public ProductNotFoundException(Long productId) {
        super("Product not found: " + productId);
    }
}

2.3. Продумаю edge cases

  • Товара нет
  • Пользователя нет
  • Товар неактивный
  • Недостаточно товара на складе
  • Количество превышает лимит
  • Race condition: два запроса одновременно

Фаза 3: Разработка (1 час)

3.1. Service слой

@Service
@Transactional
public class CartService {
    private final CartRepository cartRepository;
    private final ProductRepository productRepository;
    private final Logger logger = LoggerFactory.getLogger(CartService.class);
    
    public CartResponse addToCart(Long userId, Long productId, int quantity) {
        logger.info("Adding product {} quantity {} to cart for user {}", 
                    productId, quantity, userId);
        
        // Валидация товара
        Product product = productRepository.findById(productId)
            .orElseThrow(() -> new ProductNotFoundException(productId));
        
        if (!product.isActive()) {
            throw new ProductUnavailableException(productId);
        }
        
        if (product.getStock() < quantity) {
            throw new InsufficientStockException(productId, quantity);
        }
        
        // Получаем или создаём корзину
        Cart cart = cartRepository.findByUserId(userId)
            .orElseGet(() -> createCart(userId));
        
        // Добавляем или обновляем item
        CartItem item = cart.getItems().stream()
            .filter(i -> i.getProduct().getId().equals(productId))
            .findFirst()
            .orElseGet(() -> createCartItem(cart, product));
        
        item.setQuantity(item.getQuantity() + quantity);
        
        // Сохраняем
        cart = cartRepository.save(cart);
        logger.info("Product added successfully to cart {}", cart.getId());
        
        return mapToResponse(cart);
    }
}

3.2. Controller слой

@RestController
@RequestMapping("/api/v1/carts")
public class CartController {
    private final CartService cartService;
    private final Logger logger = LoggerFactory.getLogger(CartController.class);
    
    @PostMapping("/items")
public ResponseEntity<CartResponse> addToCart(
            @Valid @RequestBody AddToCartRequest request,
            @AuthenticationPrincipal User user) {
        
        logger.info("POST /carts/items from user {}", user.getId());
        
        CartResponse response = cartService.addToCart(
            user.getId(),
            request.getProductId(),
            request.getQuantity()
        );
        
        return ResponseEntity
            .status(HttpStatus.OK)
            .body(response);
    }
}

3.3. Exception handling

@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(ProductNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleProductNotFound(
            ProductNotFoundException e) {
        return ResponseEntity.status(404)
            .body(new ErrorResponse("PRODUCT_NOT_FOUND", e.getMessage()));
    }
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidationError(
            MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getFieldErrors()
            .stream()
            .map(FieldError::getDefaultMessage)
            .collect(Collectors.joining(", "));
        
        return ResponseEntity.status(400)
            .body(new ErrorResponse("VALIDATION_ERROR", message));
    }
}

Фаза 4: Тестирование (30 минут)

4.1. Запустить unit тесты

mvn test -Dtest=CartServiceTest

4.2. Интеграционные тесты

@SpringBootTest
@AutoConfigureMockMvc
public class CartControllerIntegrationTest {
    @Autowired
    private MockMvc mockMvc;
    
    @Test
    void shouldAddToCart_whenValidRequest() throws Exception {
        mockMvc.perform(post("/api/v1/carts/items")
            .contentType(MediaType.APPLICATION_JSON)
            .content("{\"productId\": 123, \"quantity\": 2}")
            .with(authentication(user("testuser").build())))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.cartId").exists())
            .andExpect(jsonPath("$.items[0].quantity").value(2));
    }
}

4.3. Проверить код

mvn spotbugs:check  # Поиск потенциальных bugs
mvn pmd:check       # Проверка качества кода

Фаза 5: Code Review (20 минут)

Передам на review коллегам. Проверю:

  • Логика корректна?
  • Тесты достаточны?
  • Нет ли race conditions?
  • Обработка ошибок правильная?
  • Документация (javadoc, README) достаточна?

Фаза 6: Развёртывание (10 минут)

# Создам PR
git commit -m "feat: add product to cart endpoint"
git push origin cart-feature

# После approval
git checkout main
git pull
# CI/CD pipeline запустится автоматически

Сроки

  • Анализ: 30 минут (30%)
  • Проектирование: 30 минут (30%)
  • Разработка: 60 минут (30%)
  • Тестирование: 30 минут (30%)
  • Code review: 20 минут

Всего: ~3 часа на простую задачу.

Итеративный процесс

Если во время разработки обнаружу проблему — вернусь на шаг назад:

  • Понял, что тест неправильный — переделаю тест
  • Понял, что дизайн API плохой — обсужу с team lead
  • Понял, что нужна дополнительная миграция — добавлю в план

Вывод

Мой процесс:

  1. Анализ требований и архитектуры
  2. Проектирование с TDD (тесты сначала)
  3. Разработка слоя за слоем
  4. Тестирование (unit + интеграция)
  5. Code review
  6. Развёртывание

Это гарантирует качество, предсказуемость и минимум багов.