15 промтов для Java-разработчика: от легаси-кода до высоконагруженных микросервисов

Когда я впервые попробовал использовать нейросети для написания кода, я думал, что это просто игрушка для генерации hello world. Но после того как я применил промты для рефакторинга легаси-проекта на Java 8, я понял: это инструмент, который реально экономит часы. В этой статье я собрал 15 проверенных промтов, которые помогут вам пройти путь от идеи до продакшена, используя Spring Boot, микросервисы и оптимизацию. Каждый промт сопровождается примером и пояснением, как его адаптировать под вашу задачу.

1. Генерация CRUD-контроллера за минуты

Задача: Создать REST-контроллер для сущности User с основными операциями.

Промт:

Сгенерируй Spring Boot контроллер для сущности User с полями id, name, email. Включи методы GET /users, GET /users/{id}, POST /users, PUT /users/{id}, DELETE /users/{id}. Используй ResponseEntity для обработки ошибок и валидацию через @Valid.

Пример результата:

@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    public List<User> getAllUsers() {
        return userService.findAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return userService.findById(id)
                .map(ResponseEntity::ok)
                .orElseGet(() -> ResponseEntity.notFound().build());
    }

    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
        User saved = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(saved);
    }

    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @Valid @RequestBody User user) {
        return userService.update(id, user)
                .map(ResponseEntity::ok)
                .orElseGet(() -> ResponseEntity.notFound().build());
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.delete(id);
        return ResponseEntity.noContent().build();
    }
}

Почему это работает: Промт задает структуру и ожидания, нейросеть генерирует шаблонный код, который вы можете адаптировать под свою логику.

2. Проектирование схемы базы данных

Задача: Спроектировать схему для интернет-магазина с учетом связей.

Промт:

Создай схему базы данных для интернет-магазина с таблицами: Product, Category, Order, OrderItem. Укажи поля, типы, ограничения (PRIMARY KEY, FOREIGN KEY, NOT NULL). Используй PostgreSQL синтаксис.

Пример результата:

CREATE TABLE category (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL UNIQUE
);

CREATE TABLE product (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    price NUMERIC(10, 2) NOT NULL CHECK (price > 0),
    category_id INTEGER NOT NULL REFERENCES category(id)
);

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE order_item (
    id SERIAL PRIMARY KEY,
    order_id INTEGER NOT NULL REFERENCES orders(id),
    product_id INTEGER NOT NULL REFERENCES product(id),
    quantity INTEGER NOT NULL CHECK (quantity > 0),
    price NUMERIC(10, 2) NOT NULL
);

Совет: Уточните в промте, какую СУБД вы используете, чтобы получить точный синтаксис.

3. Написание юнит-тестов с Mockito

Задача: Покрыть тестами сервисный слой.

Промт:

Напиши юнит-тесты для UserService с использованием JUnit 5 и Mockito. Протестируй методы create, update, delete. Используй @ExtendWith(MockitoExtension.class).

Пример результата:

@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    void createUser_shouldReturnSavedUser() {
        User user = new User("John", "john@example.com");
        when(userRepository.save(user)).thenReturn(user);

        User result = userService.create(user);

        assertNotNull(result);
        assertEquals("John", result.getName());
        verify(userRepository).save(user);
    }

    @Test
    void updateUser_shouldUpdateFields() {
        User existing = new User("John", "john@example.com");
        existing.setId(1L);
        User updated = new User("Johnny", "johnny@example.com");
        updated.setId(1L);

        when(userRepository.findById(1L)).thenReturn(Optional.of(existing));
        when(userRepository.save(existing)).thenReturn(updated);

        Optional<User> result = userService.update(1L, updated);

        assertTrue(result.isPresent());
        assertEquals("Johnny", result.get().getName());
    }

    @Test
    void deleteUser_shouldCallDelete() {
        userService.delete(1L);
        verify(userRepository).deleteById(1L);
    }
}

Важно: Тесты — это не роскошь, а необходимость. Промты помогают быстро генерировать тестовые сценарии, но не забывайте адаптировать их под свои кейсы.

4. Рефакторинг легаси-кода

Задача: Улучшить читаемость и структуру старого кода.

Промт:

Отрефактори следующий код: [вставьте код]. Разбей на методы, используй Stream API, избегай дублирования. Объясни изменения.

Пример результата:
До:

List<String> names = new ArrayList<>();
for (User user : users) {
    if (user.getAge() > 18) {
        names.add(user.getName().toUpperCase());
    }
}

После:

List<String> names = users.stream()
        .filter(user -> user.getAge() > 18)
        .map(user -> user.getName().toUpperCase())
        .collect(Collectors.toList());

Почему это полезно: Промт позволяет быстро получить чистый код, но всегда проверяйте логику.

5. Оптимизация SQL-запросов

Задача: Найти и исправить медленные запросы.

Промт:

Объясни, почему следующий запрос медленный: [вставьте SQL]. Предложи оптимизации: индексы, переписывание, использование EXISTS вместо IN.

Пример результата:
Для запроса:

SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE name = 'John');

Оптимизированный вариант:

SELECT o.* FROM orders o JOIN users u ON o.user_id = u.id WHERE u.name = 'John';

Совет: Используйте EXPLAIN ANALYZE для проверки.

6. Написание Dockerfile для Spring Boot

Задача: Создать Dockerfile для многоэтапной сборки.

Промт:

Создай Dockerfile для Spring Boot приложения с использованием многоэтапной сборки: первый этап — сборка с Maven, второй — запуск с JRE. Используй OpenJDK 17.

Пример результата:

FROM maven:3.8.4-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests

FROM openjdk:17-jre-slim
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Замечание: Убедитесь, что версии соответствуют вашему проекту.

7. Создание микросервиса с Spring Cloud

Задача: Сгенерировать каркас микросервиса с регистрацией в Eureka.

Промт:

Создай Spring Boot приложение с зависимостями: spring-cloud-starter-netflix-eureka-client, spring-boot-starter-web. Добавь конфигурацию для подключения к Eureka.

Пример результата:
Файл application.yml:

spring:
  application:
    name: user-service
server:
  port: 8081
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

8. Генерация Docker Compose для стека

Задача: Создать docker-compose для приложения с PostgreSQL и Redis.

Промт:

Напиши docker-compose.yml для Spring Boot приложения, PostgreSQL 14 и Redis 7. Добавь healthcheck для каждого сервиса.

Пример результата:

version: '3.8'
services:
  db:
    image: postgres:14
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

  app:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy

9. Написание CI/CD пайплайна

Задача: Создать GitHub Actions workflow для сборки и деплоя.

Промт:

Создай GitHub Actions workflow для Java проекта с Maven: запуск тестов, сборка JAR, публикация в Docker Hub.

Пример результата:

name: CI/CD

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
      - name: Build with Maven
        run: mvn clean package
      - name: Login to DockerHub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Build and push Docker image
        uses: docker/build-push-action@v4
        with:
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/my-app:latest

10. Профилирование и оптимизация производительности

Задача: Найти узкие места в Java-приложении.

Промт:

Предложи методы профилирования Java-приложения с помощью JProfiler или VisualVM. Объясни, как найти утечки памяти и проблемы с потоками.

Пример результата:
Используйте JVisualVM для мониторинга heap memory, дампов потоков. Для утечек — анализ heap dump с помощью Eclipse MAT.

11. Написание асинхронного кода с CompletableFuture

Задача: Реализовать параллельные вызовы.

Промт:

Напиши пример использования CompletableFuture для параллельного вызова двух сервисов и объединения результатов.

Пример результата:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> service1.call());
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> service2.call());

String result = future1.thenCombine(future2, (r1, r2) -> r1 + r2).join();

12. Генерация документации OpenAPI

Задача: Создать спецификацию OpenAPI для REST API.

Промт:

Сгенерируй OpenAPI спецификацию для контроллера UserController с методами CRUD. Укажи схемы User и Error.

Пример результата:

openapi: 3.0.0
info:
  title: User API
  version: 1.0.0
paths:
  /users:
    get:
      summary: Get all users
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string

13. Обработка ошибок и исключений

Задача: Создать глобальный обработчик исключений.

Промт:

Создай @RestControllerAdvice для обработки исключений в Spring Boot. Включи обработку ResourceNotFoundException, ValidationException, и общего Exception.

Пример результата:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(new ErrorResponse(ex.getMessage()));
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
        String message = ex.getBindingResult().getFieldErrors().stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.joining(", "));
        return ResponseEntity.badRequest().body(new ErrorResponse(message));
    }
}

14. Написание миграций с Flyway

Задача: Создать миграцию для добавления таблицы.

Промт:

Напиши SQL миграцию для Flyway, которая создает таблицу product, если она не существует.

Пример результата:

CREATE TABLE IF NOT EXISTS product (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    price NUMERIC(10, 2) NOT NULL
);

15. Оптимизация JSON сериализации

Задача: Ускорить сериализацию Jackson.

Промт:

Как оптимизировать сериализацию Jackson в Spring Boot? Предложи настройки: включение WRITE_DATES_AS_TIMESTAMPS, использование после обработки, отключение фатальных проблем.

Пример результата:
В application.properties:

spring.jackson.serialization.write-dates-as-timestamps=false
spring.jackson.deserialization.fail-on-unknown-properties=false

Заключение

Эти промты — не серебряная пуля, но они реально ускоряют рутинные задачи. Главное — всегда проверяйте сгенерированный код, адаптируйте под свой контекст и используйте нейросети как инструмент, а не замену мышлению. Начните с простого, например, с генерации CRUD, и постепенно переходите к сложным сценариям. Удачного кодинга!

← Все статьи

Комментарии

Читайте также