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

Можешь ли рассказать о задаче которой гордишься

1.0 Junior🔥 31 комментариев
#Опыт и софт-скиллы

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

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

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

Проект, которым я гордлюсь: реальное время sync в финтех приложении

Одна из самых сложных и полезных работ, которой я гордлюсь, это реализация real-time синхронизации данных в мобильном приложении для управления инвестициями. Этот проект объединил множество навыков: архитектуру, оптимизацию, работу с БД и сетевыми технологиями.

Проблема

Приложение отправляет ордера на бирже и должно отображать цены в реальном времени. Но было несколько критических проблем:

  • Lag: данные обновлялись с задержкой в 2-3 секунды
  • Battery drain: синхронизация работала на фоне и убивала батарею за 4-5 часов активного использования
  • Network traffic: приложение отправляло 10-15 MB данных в день на холостую
  • Data consistency: иногда пользователь видел старые цены, даже после обновления
  • Offline mode: без интернета было невозможно работать с сохранённые данными

Решение архитектуры

1. WebSocket вместо HTTP polling

// ДО: HTTP polling каждые 2 секунды
timer.scheduleAtFixedRate(2000) {
    api.getPrices()  // 50 KB на запрос
}

// ПОСЛЕ: WebSocket с дельта-обновлениями
webSocket.onMessage { message ->
    val delta = PriceDelta.fromJson(message)
    pricesRepository.updatePrice(delta.symbol, delta.newPrice)
}

Результат: падение трафика с 15 MB/день до 200 KB/день.

2. Локальный SQLite кеш с Room ORM

@Entity(tableName = "prices")
data class PriceEntity(
    @PrimaryKey val symbol: String,
    val price: Double,
    val timestamp: Long,
    @ColumnInfo(name = "is_synced") val isSynced: Boolean
)

// Оффлайн режим: пользователь работает с кешем
pricesDao.getAllPrices().collect { prices ->
    viewModel.updateUI(prices)
}

3. Repository паттерн для конфликт-разрешения

class PricesRepository(
    private val api: ApiService,
    private val localDb: PricesDao
) {
    fun syncPrices(): Flow<Result<Unit>> = flow {
        try {
            // 1. Получаем данные с сервера
            val remoteData = api.getPrices()
            
            // 2. Получаем локальные данные
            val localData = localDb.getAll()
            
            // 3. Разрешаем конфликты: серверные данные всегда новее
            val merged = merge(localData, remoteData)
            
            // 4. Сохраняем в БД
            localDb.upsertAll(merged)
            
            emit(Result.success(Unit))
        } catch (e: Exception) {
            emit(Result.failure(e))
        }
    }
}

4. Оптимизация использования батареи

class PriceSyncWorker : CoroutineWorker() {
    override suspend fun doWork(): Result {
        return try {
            // WorkManager + adaptive constraints
            val constraints = Constraints.Builder()
                .setRequiresCharging(false)         // Работаем когда не на зарядке
                .setRequiredNetworkType(CONNECTED) // Только при интернете
                .setBatteryLow(false)              // Не на низком заряде
                .build()
            
            val syncRequest = PeriodicWorkRequestBuilder<PriceSyncWorker>(
                15, TimeUnit.MINUTES  // Синк каждые 15 минут, не 2 сек
            ).setConstraints(constraints).build()
            
            WorkManager.getInstance(context).enqueueUniquePeriodicWork(
                "price_sync",
                ExistingPeriodicWorkPolicy.KEEP,
                syncRequest
            )
            
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }
}

Технологический стек

  • Kotlin Coroutines для асинхронности (вместо RxJava)
  • Room ORM для локального кеша
  • OkHttp 4.x с поддержкой WebSocket
  • Repository паттерн для разделения слоёв
  • WorkManager для фоновых задач с ограничениями батареи
  • Flow для реактивности
  • Hilt для dependency injection

Результаты

МетрикаДоПослеУлучшение
Задержка обновления2-3 сек50-100 мс30-60x
Трафик в день15 MB200 KB75x
Время батареи4-5 часов18-20 часов4-5x
Загруженность CPU45%5%9x
Offline режимНетДа+100%

Что я выучил

  1. Архитектура имеет значение: выбор WebSocket вместо HTTP полностью переформатировал приложение
  2. Локальный кеш — король: Room ORM сделал оффлайн режим естественным
  3. WorkManager лучше Timer: constraints и батарея-aware синхронизация
  4. Repository паттерн спасает жизнь: чистое разделение между локальными и удалённых данными
  5. Тестирование критично: я написал 150+ тестов для конфликт-разрешения логики

На собеседовании

Этот проект демонстрирует:

  • System design: понимание trade-offs между производительностью и батареей
  • Architecture: repository паттерн, разделение слоёв (data/domain/presentation)
  • Modern Android: Coroutines, Room, WorkManager
  • Problem solving: переход с polling на WebSocket
  • Метрики: я измеряю результаты (не просто "сделал быстрее")
  • User-centric: заботишься о батарее, трафике, оффлайн режиме

Вот такой проект, где я не просто писал код, а решал реальные проблемы пользователей и понимал архитектурные решения в контексте бизнеса.

Можешь ли рассказать о задаче которой гордишься | PrepBro