Какой был грейд (уровень) на прошлом проекте?

Ответ

На прошлом проекте я занимал позицию Middle Java Developer.

Основные обязанности и зона ответственности:

  1. Разработка: Создание и поддержка бизнес-логики, REST API (Spring Boot).
  2. Работа с данными: Оптимизация запросов и работа с БД (PostgreSQL, Hibernate).
  3. Интеграция: Взаимодействие с очередями (Kafka) и кэшем (Redis).
  4. Качество кода: Написание unit- и integration-тестов (JUnit, Mockito), участие в code review.
  5. Работа в команде: Участие в планировании спринтов, помощь junior-разработчикам.

Пример типичной реализации:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private CacheService cacheService;

    @Override
    @Transactional(readOnly = true)
    public UserDto getUserById(Long id) {
        // Проверка кэша перед запросом к БД
        String cacheKey = "user:" + id;
        UserDto cachedUser = cacheService.get(cacheKey, UserDto.class);
        if (cachedUser != null) {
            return cachedUser;
        }
        // Запрос к БД и маппинг сущности в DTO
        User user = userRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("User not found"));
        UserDto userDto = mapToDto(user);
        // Сохранение в кэш
        cacheService.put(cacheKey, userDto, Duration.ofMinutes(10));
        return userDto;
    }
}

Ответ 18+ 🔞

А, ну вот, смотри, классика жанра, блядь! Middle Java Developer, говоришь? Это ж как тот самый Герасим из рассказа, только вместо метлы — IntelliJ IDEA, а вместо Муму — баг в коде, который ты сам же и создал, а потом, блядь, с горячей душой, пытаешься утопить в дебаггере!

Основная твоя зона, значит, была — не пиздеть, а делать. Ну то есть:

  1. Разработка. Писать эту самую бизнес-хуйню на Spring Boot, чтобы какой-нибудь API, блядь, не падал, когда ему прилетает запрос не с тем JSON'ом. REST, сука, как мантра: GET, POST, PUT, DELETE — в рот меня чих-пых, и чтобы всё летало.
  2. Работа с данными. А это святое, ёпта! База данных — она как та самая княгиня из сказки: капризная, блядь. Напишешь кривой запрос через Hibernate — она тебе такой N+1 проблемой вьебет, что мало не покажется. Оптимизация — это когда ты уже наступил на эти грабли, получил по ебалу от продакшена и теперь сидишь, переписываешь, чтоб быстрее было.
  3. Интеграция. Очереди Kafka — это чтобы все микросервисы, как мартышлюшки на дереве, переругивались сообщениями. А Redis — это такая хитрая жопа, куда всё складываешь на время, чтобы лишний раз в базу не лезть. Главное — не забыть туда положить и вовремя оттуда достать, а то будет пиздец.
  4. Качество кода. Ага, unit-тесты. Пишешь их, будто заклинания от злых духов. Потом приходит коллега на code review, смотрит и говорит: «Ты чё, мудак, тут Mockito'м всё заmockил, а интеграцию не проверил?». И ты такой: «Да похуй, главное coverage 80%». А в душе — волнение ебать.
  5. Работа в команде. Это когда на планировании спринта все такие умные, рисуют схемы, а потом выясняется, что задача, которую оценили в два дня, на самом деле — овердохуища работы. А ещё juniors помогать — это как учить того самого Буратино: вроде и деревянный, но если правильно объяснить — может и золотой ключик найти (то есть, баг пофиксить).

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

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository; // Это наш Герасим, который в базу ходит
    @Autowired
    private CacheService cacheService; // А это — его тайный сундук, где он прячет находки

    @Override
    @Transactional(readOnly = true)
    public UserDto getUserById(Long id) {
        // Первым делом, хитрая жопа, лезем в кэш. Авось, уже кто-то туда положил.
        String cacheKey = "user:" + id;
        UserDto cachedUser = cacheService.get(cacheKey, UserDto.class);
        if (cachedUser != null) {
            return cachedUser; // Ура, ёпта! Не пришлось базу ебашить!
        }
        // Не повезло, сука. Придётся Герасима будить, пусть идёт в базу копаться.
        User user = userRepository.findById(id)
                .orElseThrow(() -> new ResourceNotFoundException("User not found")); // Если не нашёл — пизда, исключение летит
        UserDto userDto = mapToDto(user); // Превращаем запылённую сущность в красивый DTO
        // А теперь, чтоб два раза не вставать, засунем это добро в кэш. На десять минут, не жадничаем.
        cacheService.put(cacheKey, userDto, Duration.ofMinutes(10));
        return userDto;
    }
}

Вот и вся магия, блядь. Смотришь на такой код и думаешь: «Муму...». Вроде и просто, а если накосячить — либо перформанс накроется медным тазом, либо данные кривые вернутся. А потом сидишь и думаешь: «Что же я, мудак, сделал?». Но в этом и есть вся наша работа, ёперный театр!