Опишите интересный баг, с которым вы столкнулись

Ответ

Баг с некорректной инвалидацией кеша в мобильном приложении.

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

Пример проблемного кода на Kotlin:

fun loadData() {
    val cachedData = cache.get("key")
    if (cachedData != null) {
        showData(cachedData) // Использование устаревших данных
        return // Свежие данные не запрашивались
    }
    // ... загрузка с сети
}

Решение и почему оно важно:

  1. Добавлена принудительная инвалидация кеша при пользовательских действиях, изменяющих данные (например, «pull-to-refresh»).
  2. Внедрена проверка версий (ETag/Last-Modified): при запросе данных отправляется хэш или метка времени текущей копии; сервер возвращает новые данные только если они изменились (статус 200), иначе — «Not Modified» (304). Это оптимизирует трафик.

Почему баг был интересен: Он проявлялся только в специфическом сценарии (после фонового обновления данных на сервере) и требовал понимания полного цикла данных: сервер → сеть → кеш → UI.

Ответ 18+ 🔞

Да ты посмотри, какой прикол-то вылез! Приложение, сука, как будто застряло во вчерашнем дне. На сервере данные уже новые, а у пользователя в телефоне — всё та же старая пиздобратия. И ведь API-то отвечает правильно, свежак отдаёт! А на экране — хуй с горы, вчерашние объедки.

Весь фокус в том, что кеш, блядь, никто не заставлял обновляться. Смотрит код в хранилище, а там что-то лежит — ну и пиздуй показывает, зачем сеть грузить? Успокоился, довольный.

Вот смотри, как это выглядело, этот кусок гениальности:

fun loadData() {
    val cachedData = cache.get("key")
    if (cachedData != null) {
        showData(cachedData) // Использование устаревших данных
        return // Свежие данные не запрашивались
    }
    // ... загрузка с сети
}

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

Как мы эту мартышлюшку починили:

  1. Впендюрили принудительную инвалидацию. Пользователь тянет экран, чтобы обновить — мы тут же, блядь, весь кеш по этому ключу в тартарары. Чисто, жёстко, без вариантов. Сам просил свежего — получи.
  2. Научили приложение хитрить, как жопа с ручками. Теперь оно, прежде чем слепо брать из кеша, шлёт на сервер намёк: «Э, чувак, у меня вот такая версия данных, ты глянь, у тебя что?». А сервер, если ничего нового нет, отвечает: «Да похуй, сиди на старом» (статус 304). А если есть — тогда уже отгружает полный ответ. Трафик экономится, пользователь не ждёт как лох, красота.

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