PrepBro
Профессии
PrepBro
Профессия:

Подготовка

  • Вопросы537
  • Задачи23

Аналитика

  • hh статистика
  • Анализ резюме

Практика

  • Тестовое собеседование
  • Mock-собеседование
  • Менторы

Поддержка / отзывы

Telegram админа
Профессия:

Подготовка

  • Вопросы537
  • Задачи23

Аналитика

  • hh статистика
  • Анализ резюме

Практика

  • Тестовое собеседование
  • Mock-собеседование
  • Менторы

Поддержка / отзывы

Telegram админа
Все 24 профессии
Android DeveloperData AnalystSystem Analyst1С DeveloperiOS DeveloperBusiness AnalystJava DeveloperData ScientistQA EngineerQA AutomationPHP BackendC/C++ BackendDevOps EngineerIT Project ManagerFrontend DeveloperNode.js BackendUnity DeveloperC# BackendProduct AnalystFlutter DeveloperPython DeveloperIT Product ManagerGo DeveloperData Engineer

© 2026 PrepBro. Все права защищены.

Telegram-бот

Вопросы по Flutter Developer

Как работать с JSON и сериализацией данных во Flutter?
1.6 Junior🔥 30💬 2

JSON и сериализация данных во Flutter

Сериализация — это фундаментальная часть мобильной разработки. Существует несколько подходов с разными trade-offs.

1. Встроенная сериализация через jsonDecode

import 'dart:convert';

// Простой класс пользователя
class User {
  final int id;
  final String name;
  final String email;
  
  User({
    required this.id,
    required this.name,
    required this.email,
  });
  
  // Парсинг из JSON
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'] as int,
      name: json['name'] as String,
      email: json['email'] as String,
    );
  }
  
  // Конвертация в JSON
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'email': email,
    };
  }
}

// Использование
final json = '{"id": 1, "name": "John", "email": "john@example.com"}';
final jsonData = jsonDecode(json);
final user = User.fromJson(jsonData);
Читать полностью ->
Что такое контекст в Dart?
1.3 Junior🔥 30💬 2

Context в Flutter/Dart — контекст построения виджета

Context (BuildContext) — это объект, который содержит информацию о позиции виджета в дереве виджетов (widget tree). Он предоставляет доступ к различным сервисам Flutter и является ключевым компонентом при разработке Flutter приложений.

Основная идея

Context служит для:

  • Навигации — переход между экранами (Navigator.push)
  • Доступ к Theme — получение текущей темы приложения
  • Управление State — доступ к родительским виджетам (Provider, GetX)
  • Показ диалогов — showDialog, showModalBottomSheet
  • Media Query — получение размеров экрана, ориентации
  • Управление Focus — фокус на текстовых полях

Получение Context

// Context доступен в методе build
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // context доступен здесь
    return Text('Hello');
  }
}
Читать полностью ->
Приведи пример использования FutureBuilder
1.0 Junior🔥 30💬 1

Пример использования FutureBuilder

FutureBuilder — это виджет, который позволяет асинхронно загружать данные и обновлять UI в зависимости от состояния Future. Это один из наиболее часто используемых паттернов в Flutter для работы с асинхронными операциями.

Базовый пример

class UserProfilePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<User>(
      future: fetchUser(userId: "123"),
      builder: (context, snapshot) {
        // Проверяем состояние Future
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return Center(child: Text("Error: ${snapshot.error}"));
        } else if (snapshot.hasData) {
          return UserCard(user: snapshot.data!);
        } else {
          return Center(child: Text("No data"));
        }
      },
    );
  }
}
Читать полностью ->
Что такое state в state management?
1.2 Junior🔥 30💬 1

State в управлении состоянием

State (состояние) — это данные, которые определяют текущее поведение и внешний вид приложения в конкретный момент времени. Это ключевое понятие в управлении состоянием (state management).

Определение и суть

State — это совокупность данных, которая:

  • Определяет, как выглядит приложение в настоящий момент
  • Может изменяться в ответ на действия пользователя или события
  • Влияет на поведение компонентов и логику приложения

Примеры state:

  • Авторизован ли пользователь
  • Данные товаров в корзине
  • Текущий экран (маршрут)
  • Значения формы
  • Список загруженных статей

Типы State

1. UI State (состояние интерфейса)

Данные, связанные с представлением:

class UIState {
  final bool isLoading;
  final String? errorMessage;
  final String selectedTab;
  final bool isDarkMode;
  
  UIState({
    this.isLoading = false,
    this.errorMessage,
    this.selectedTab = home,
    this.isDarkMode = false,
  });
}
Читать полностью ->
Что выберешь GetX или BLoC?
2.0 Middle🔥 30💬 1

GetX vs BLoC: Выбор State Management'а

Введение

Это классический вопрос в Flutter сообществе, и ответ не абсолютный — всё зависит от контекста. После 10+ лет я выбрал бы ни то, ни другое, а вместо этого — Provider или Riverpod. Но давайте разберёмся со обоими.

GetX: Обзор

Что это?

GetX — это инструмент all-in-one для state management, navigation, dependency injection и ещё кучи всего.

// GetX example
class CounterController extends GetxController {
  final count = 0.obs;
  
  void increment() => count++;
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Obx(() => Text('Count: ${Get.find<CounterController>().count}')),
      floatingActionButton: FloatingActionButton(
        onPressed: () => Get.find<CounterController>().increment(),
        child: Icon(Icons.add),
      ),
    );
  }
}

// main.dart
Get.put(CounterController()); // DI

Преимущества GetX ✅

Читать полностью ->
Что такое дерево виджетов?
1.0 Junior🔥 30💬 1

Дерево виджетов в Flutter

Widget Tree (дерево виджетов) — это иерархическая структура, в которой все UI элементы приложения организованы в виде дерева. Каждый виджет может иметь дочерние виджеты, создавая древовидную структуру от корня (MyApp) к листьям (Text, Image).

Структура дерева

MyApp
├── MaterialApp
│   ├── home: HomePage
│   │   ├── Scaffold
│   │   │   ├── appBar: AppBar
│   │   │   │   └── title: Text
│   │   │   ├── body: Column
│   │   │   │   ├── Row
│   │   │   │   │   ├── Icon
│   │   │   │   │   └── Text
│   │   │   │   └── ListView
│   │   │   │       └── ListTile (repeated)
│   │   │   └── floatingActionButton: FloatingActionButton
│   │   │       └── Icon

Элементы дерева

1. Widget — объявление UI (неизменяемо):

// Widget описывает КАК должен выглядеть UI
text = Text('Hello', style: TextStyle(fontSize: 18));

2. Element — экземпляр Widget в дереве:

Читать полностью ->
Что такое абстракция?
1.0 Junior🔥 29💬 2

Абстракция

Абстракция — это принцип объектно-ориентированного программирования (ООП), который скрывает сложные детали реализации и предоставляет только необходимый интерфейс для использования. Абстракция позволяет работать с объектами на высоком уровне, не волнуясь о том, как они устроены внутри.

Суть абстракции

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

  • Как завести машину
  • Как нажимать педали
  • Как рулить

Аналлогично в программировании: пользователь класса не должен знать о его внутренней реализации.

Абстракция через интерфейсы и классы

Без абстракции (ПЛОХО)

Читать полностью ->
Что такое ООП?
1.0 Junior🔥 29💬 1

Что такое ООП (Объектно-ориентированное программирование)

ООП — это парадигма программирования, которая организует код вокруг объектов — сущностей, содержащих данные (свойства) и методы (поведение). Это один из самых популярных подходов к разработке, особенно в Dart и Flutter.

Четыре столпа ООП

1. Инкапсуляция (Encapsulation)

Это скрытие внутреннего состояния объекта и предоставление контролируемого доступа через public интерфейс.

class BankAccount {
  // Private переменная
  double _balance = 0;
  
  // Public метод для безопасного доступа
  void deposit(double amount) {
    if (amount > 0) {
      _balance += amount;
    }
  }
  
  // Getter для получения значения
  double get balance => _balance;
}

void main() {
  final account = BankAccount();
  account.deposit(100);
  print(account.balance); // 100
}

2. Наследование (Inheritance)

Читать полностью ->
Что такое initState(), didChangeDependencies() и dispose()?
1.0 Junior🔥 28💬 2

initState(), didChangeDependencies() и dispose()

Это методы жизненного цикла StatefulWidget. Понимание их порядка и использования — критично для правильного управления ресурсами.

Жизненный цикл StatefulWidget

Читать полностью ->
Какие архитектурные паттерны используются во Flutter (MVP, MVVM, Clean Architecture)?
3.0 Senior🔥 28💬 2

Архитектурные паттерны во Flutter

Архитектура определяет качество, масштабируемость и maintainability проекта. Рассмотрю три основных подхода.

1. MVC (Model-View-Controller) — старый подход

Одна из первых архитектур, но во Flutter редко используется.

┌─────────────┐
│  Controller │
│   (Logic)   │
└──────┬──────┘
       │
       ├──→ Model (State, Data)
       └──→ View (UI)

Проблемы:
- Controller быстро становится жирным
- Сложно тестировать UI
- Tight coupling между компонентами

2. MVP (Model-View-Presenter) — лучше, но громоздко

┌─────────────────────────────────┐
│         Presenter               │
│  (Business Logic & UI Logic)    │
└─────────────────────────────────┘
    ↓ implements          ↑ updates
┌─────────────┐       ┌──────────┐
│   View      │       │  Model   │
│  (UI только)│       │ (Data)   │
└─────────────┘       └──────────┘
Читать полностью ->
Какие способы управления состоянием (State Management) существуют во Flutter?
2.0 Middle🔥 28💬 2

Способы управления состоянием во Flutter

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

1. setState() — встроенный механизм

setState() — это самый простой и встроенный способ управления локальным состоянием в StatefulWidget:

class Counter extends StatefulWidget {
  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int count = 0;

void incrementCounter() {
    setState(() {
      count++;
    });
  }

@override
  Widget build(BuildContext context) {
    return Text("Count: $count");
  }
}

Плюсы: простота, встроенность, хорош для малых компонентов Минусы: плохо масштабируется, сложно тестировать, пересчитывает весь виджет

2. Provider — рекомендуемое решение

Читать полностью ->
Чем отличается Stateful widget от Stateless widget?
1.2 Junior🔥 28💬 2

Stateless Widget vs Stateful Widget: Когда что использовать

Это один из самых фундаментальных вопросов во Flutter. Понимание разницы между stateless и stateful виджетами критично для написания правильного и эффективного кода.

Основная разница

Stateless Widget:

  • Не имеет внутреннего состояния (state)
  • Неизменяемый (immutable)
  • Строит UI один раз и никогда не меняется
  • Быстрый и лёгкий

Stateful Widget:

  • Имеет изменяемое состояние (State)
  • Может перестраиваться (rebuild) при изменении состояния
  • Может иметь lifecycle (initState, dispose)
  • Более сложный

Stateless Widget: Простой и чистый

Пример:

class WelcomeScreen extends StatelessWidget {
  final String userName;
  
  const WelcomeScreen({required this.userName});
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Welcome')),
      body: Center(
        child: Text('Hello, $userName!'),
      ),
    );
  }
}
Читать полностью ->
Когда вызывается state dispose?
1.0 Junior🔥 28💬 1

Когда вызывается State.dispose()?

Метод dispose() — это критически важный метод в жизненном цикле StatefulWidget'а. Понимание его вызова необходимо для предотвращения утечек памяти и правильного управления ресурсами.

Основное назначение dispose()

Метод dispose() вызывается, когда State удаляется из дерева виджетов и никогда больше не будет перестроено. Это последняя возможность очистить ресурсы.

class MyScreen extends StatefulWidget {
  @override
  State<MyScreen> createState() => MyScreenState();
}
Читать полностью ->
Для чего нужен Container?
1.0 Junior🔥 28💬 1

Container в Flutter: назначение и практическое применение

Container — это один из самых часто используемых виджетов в Flutter. Это не просто контейнер, это многофункциональный строительный блок для создания интерфейсов.

Что такое Container

Container — это convenience widget (удобный виджет), который объединяет несколько других виджетов для выполнения типичных операций вёрстки:

// Container фактически эквивалентен этой комбинации:
Align(
  alignment: Alignment.center,
  child: ConstrainedBox(
    constraints: BoxConstraints.expand(),
    child: DecoratedBox(
      decoration: BoxDecoration(...),
      child: Padding(
        padding: EdgeInsets.all(16),
        child: child,
      ),
    ),
  ),
)

// Но вместо этого мы просто пишем:
Container(
  alignment: Alignment.center,
  constraints: BoxConstraints.expand(),
  decoration: BoxDecoration(...),
  padding: EdgeInsets.all(16),
  child: child,
)

Основные назначения Container

Читать полностью ->
Что такое StatelessWidget?
1.3 Junior🔥 28💬 1

StatelessWidget в Flutter

StatelessWidget — это базовый тип виджета в Flutter, который представляет неизменяемую часть пользовательского интерфейса. Это один из двух основных типов widgets в Flutter, наряду со StatefulWidget.

Определение и концепция

StatelessWidget — это виджет, который не имеет состояния. Его состояние не может изменяться во время жизненного цикла. Если нужно что-то изменить, нужно создать новый экземпляр виджета.

// StatelessWidget — неизменяемый, как константа
const StatelessWidget = FrozenUI();

Структура StatelessWidget

class MyButton extends StatelessWidget {
  final String label;
  final VoidCallback onPressed;
  
  const MyButton({
    required this.label,
    required this.onPressed,
  });

@override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      child: Text(label),
    );
  }
}
Читать полностью ->
Как работает build() метод во Flutter?
1.0 Junior🔥 27💬 2

Как работает build() метод во Flutter

Что такое build()?

build() — это метод, который описывает как выглядит виджет в данный момент. Это функция, которая возвращает дерево виджетов.

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      child: Text("Hello"),
    );
  }
}

build() вызывается в следующих ситуациях:

  1. Первый раз — при создании виджета
  2. Когда родитель пересчитывается — если родитель вызвал setState()
  3. Когда InheritedWidget изменился — если виджет использует его
  4. Когда зависимость изменилась — в Riverpod/Provider

Жизненный цикл StatelessWidget

class MyStatelessWidget extends StatelessWidget {
  const MyStatelessWidget();
Читать полностью ->
Перечисли примитивные типы данных
1.0 Junior🔥 27💬 1

Примитивные типы данных в Dart

В Dart есть несколько примитивных типов данных, которые используются для работы с базовыми значениями. Давайте разберём каждый.

1. int (целые числа)

Описание: целые числа любого размера

int age = 25;
int temperature = -10;
int hugeNumber = 9223372036854775807; // 64-bit integer
int zero = 0;

// Литералы
int decimal = 123;
int hexadecimal = 0xFF; // 255
int binary = 0b1010;    // 10

Операции:

int a = 10;
int b = 3;

print(a + b);      // 13 (сложение)
print(a - b);      // 7 (вычитание)
print(a * b);      // 30 (умножение)
print(a ~/ b);     // 3 (целочисленное деление)
print(a % b);      // 1 (остаток от деления)
print(a.abs());    // 10 (абсолютное значение)
print(a.isEven);   // false (чётное ли)
print(a.isOdd);    // true (нечётное ли)

2. double (вещественные числа)

Описание: числа с плавающей точкой (64-bit)

Читать полностью ->
Где ищешь библиотеки для Flutter?
2.0 Middle🔥 27💬 1

Где искать библиотеки для Flutter

Найти правильную библиотеку — это навык, который экономит часы разработки. Рассмотрю мой процесс и инструменты.

1. pub.dev (основной источник)

Это официальный репозиторий Dart/Flutter пакетов.

Сайт: https://pub.dev

Фильтры при поиске:
- Null Safety (обязательно ✅)
- Verified Publisher (для популярных пакетов)
- Like Count (чем больше лайков, тем надежнее)
- pub points (оценка качества кода, документации, тестов)

Критерии выбора:

❌ Библиотеки с 0 pub points (no docs, no tests)
✅ Библиотеки с 130+ pub points (хорошее качество)
❌ Последнее обновление > 1 года назад
✅ Активная разработка и maintenance

2. GitHub (для более сложных поисков)

Когда использовать:

  • Нужна библиотека, которая есть на GitHub, но не на pub.dev
  • Хотите видеть исходный код перед использованием
  • Ищете примеры использования в реальных проектах
  • Нужна самая свежая версия (не выпущена на pub.dev)

Как искать на GitHub:

Читать полностью ->
Какой паттен чаще всего используешь?
2.0 Middle🔥 27💬 1

Паттерны, которые я использую чаще всего

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

1. Паттерн Repository (самый используемый)

Это основной паттерн архитектуры, который я применяю в каждом проекте. Repository абстрагирует источник данных (API, БД, кеш) от бизнес-логики.

abstract class UserRepository {
  Future<List<User>> getUsers();
  Future<User> getUserById(String id);
  Future<void> updateUser(User user);
}
Читать полностью ->
Расскажи о себе
1.6 Junior🔥 27💬 1

О себе как Flutter разработчика

Я профессиональный разработчик с 10+ лет опыта в разработке мобильных приложений. Специализируюсь на создании высокопроизводительных и масштабируемых приложений для iOS и Android с использованием Flutter.

Опыт и навыки

В течение своей карьеры я работал над проектами различной сложности — от стартапов и MVP до крупных корпоративных приложений с миллионами пользователей. Мой опыт включает полный цикл разработки, от проектирования архитектуры до публикации в маркетплейсах.

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

Основной язык — Dart, основной фреймворк — Flutter. Хорошо знаю Swift и Kotlin для работы с платформенным кодом. Использую различные инструменты: Firebase, Stripe, Socket.io для real-time коммуникации.

Примеры проектов

Читать полностью ->
Как интегрировать REST API во Flutter приложение?
1.0 Junior🔥 26💬 2

Интеграция REST API во Flutter приложение

Работать с REST API — это ежедневная задача во Flutter разработке. Рассмотрю правильный подход от получения данных до кэширования.

1. Базовое использование http пакета

import 'package:http/http.dart' as http;
import 'dart:convert';
Читать полностью ->
Какой state manager выберешь для написания приложения с нуля?
2.7 Senior🔥 26💬 1

Выбор State Manager для нового приложения

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

Мой выбор: Riverpod

Для нового приложения я выберу Riverpod, вот почему:

Преимущества Riverpod

1. Лучшая производительность и оптимизации:

final userProvider = FutureProvider<User>((ref) async {
  return fetchUser();
});

final userGreetingProvider = Provider<String>((ref) {
  final user = ref.watch(userProvider);
  return user.when(
    data: (u) => 'Hello, ${u.name}!',
    loading: () => 'Loading...',
    error: (err, st) => 'Error',
  );
});

2. Встроенная поддержка async операций:

final postsProvider = FutureProvider<List<Post>>((ref) async {
  final response = await dio.get('/posts');
  return (response.data as List)
      .map((p) => Post.fromJson(p))
      .toList();
});
Читать полностью ->
Для чего нужны Stream?
1.0 Junior🔥 26💬 1

Для чего нужны Stream?

Stream — это один из самых мощных и фундаментальных инструментов в Dart и Flutter для асинхронной обработки данных. Это абстракция, которая позволяет работать с последовательностями событий, поступающих во времени.

Основное назначение Stream

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

  • Данные поступают асинхронно — с сервера, из файлов, с датчиков
  • Нужно реагировать на изменения — обновление состояния в реальном времени
  • Обработка множественных событий — клики пользователя, сообщения, уведомления
  • Работа с веб-сокетами — live-данные, chat-приложения

Основные типы Stream

Single-subscription Stream — может иметь только одного слушателя:

Stream<int> numbersStream = Stream<int>.periodic(
  Duration(seconds: 1),
  (count) => count,
).take(5);
Читать полностью ->
Приведи пример использования StreamBuilder
2.0 Middle🔥 26💬 1

StreamBuilder в Flutter: работа с асинхронными потоками данных

StreamBuilder — это виджет, позволяющий строить UI на основе Stream данных. Это одна из самых важных техник реактивного программирования в Flutter.

Что такое StreamBuilder

StreamBuilder — это виджет, который "слушает" Stream и перестраивается каждый раз, когда в Stream поступляют новые данные. Это идеально подходит для реактивного обновления UI.

Читать полностью ->
Что такое async, await и Future в Dart?
1.6 Junior🔥 25💬 2

Async, Await и Future в Dart

Future — асинхронное значение

Future — это объект, который представляет будущее значение, которое может быть доступно со временем или вызвать ошибку:

// Future завершится одним из трёх состояний:
// 1. Успешно (resolved) с значением
// 2. Ошибка (rejected) с исключением
// 3. В ожидании (pending) — ещё не завершён

Future<String> fetchUserName() {
  // Эта функция вернёт значение через 2 секунды
  return Future.delayed(
    Duration(seconds: 2),
    () => "John Doe",
  );
}

// Использование Future
final future = fetchUserName();
// future содержит обещание получить имя позже

Обработка Future с .then()

fetchUserName().then((name) {
  print("User: $name");
}).catchError((error) {
  print("Error: $error");
}).whenComplete(() {
  print("Request finished");
});

// Цепочка операций
Future<int> getUserAge(String name) {
  return Future.delayed(
    Duration(seconds: 1),
    () => 30,
  );
}
Читать полностью ->
Как тестировать Flutter-приложения? Какие виды тестов существуют?
2.0 Middle🔥 25💬 2

Тестирование во Flutter

Три типа тестов

Фреймворк Flutter поддерживает три основных вида тестирования:

┌─────────────────────────────────────────────┐
│           Unit Tests (Юнит-тесты)          │
│  Тестирование отдельных функций, классов  │
│  Быстро | Не нужен эмулятор | Просто      │
└─────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────┐
│         Widget Tests (Виджет-тесты)        │
│  Тестирование UI компонентов и виджетов   │
│  Средняя скорость | Изолированные тесты   │
└─────────────────────────────────────────────┘
       ↓
┌─────────────────────────────────────────────┐
│   Integration Tests (E2E тесты)            │
│  Полное приложение от начала до конца     │
│  Медленно | Нужен эмулятор | Реальные BL  │
└─────────────────────────────────────────────┘

1. Unit Tests (Юнит-тесты)

Тестируем функции, классы, логику БЕЗ UI:

import "package:flutter_test/flutter_test.dart";
Читать полностью ->
Как выполнять сетевые запросы во Flutter?
1.0 Junior🔥 25💬 2

Сетевые запросы во Flutter

Встроенный пакет http

http — это встроенный пакет Flutter для выполнения HTTP запросов. Это простой и лёгкий способ:

import "package:http/http.dart" as http;

// GET запрос
Future<void> fetchUserData() async {
  try {
    final response = await http.get(
      Uri.parse("https://api.example.com/users/1"),
      headers: {
        "Authorization": "Bearer token",
        "Content-Type": "application/json",
      },
    );

if (response.statusCode == 200) {
      print(response.body);
    } else {
      print("Error: ${response.statusCode}");
    }
  } catch (e) {
    print("Error: $e");
  }
}

// POST запрос
Future<void> createUser() async {
  final response = await http.post(
    Uri.parse("https://api.example.com/users"),
    headers: {"Content-Type": "application/json"},
    body: jsonEncode({
      "name": "John",
      "email": "john@example.com",
    }),
  );

if (response.statusCode == 201) {
    print("User created");
  }
}
Читать полностью ->
Что такое однопоточность?
1.2 Junior🔥 25💬 1

Что такое однопоточность

Однопоточность (single-threaded) — это модель выполнения, при которой приложение выполняет только один процесс за раз в главном потоке. Dart и Flutter используют однопоточную модель с асинхронным программированием.

Основные концепции

Однопоточность означает:

  • В один момент времени выполняется только одна операция
  • Нет конкурентного доступа к переменным
  • Нет race conditions
  • Нет deadlocks
  • Но есть заблокирование UI при долгих операциях
void main() {
  // Dart выполняет код последовательно
  print("1"); // выполнится первым
  print("2"); // выполнится вторым
  print("3"); // выполнится третьим
  
  // Результат: 1, 2, 3
}

Как это работает в Dart

Event Loop (Цикл событий):

// Dart использует Event Loop для управления асинхронностью
Читать полностью ->
Что такое git merge?
1.2 Junior🔥 25💬 2

Git Merge

Git merge — операция объединения двух или более веток (branches) в одну. Это один из основных инструментов командной разработки, позволяющий интегрировать изменения из разных веток в основную ветку проекта.

Основной концепт

Вы работаете в отдельной ветке feature/auth, создаёте коммиты с новой функциональностью, а затем хотите объединить эти изменения в ветку main. Для этого используется git merge:

git checkout main
git merge feature/auth

Fast-forward merge создаёт новый коммит, объединяющий истории обеих веток.

Типы Merge

1. Fast-Forward Merge

Это самый простой случай. Если main не имел изменений с момента создания feature/auth, Git просто перемещает указатель main на последний коммит feature/auth:

main:  A → B → C
feature/auth:     → D → E
После merge: A → B → C → D → E

Команда:

git merge feature/auth  # Fast-forward

2. Three-Way Merge

Используется, когда обе ветки имеют расходящиеся истории:

Читать полностью ->
Приведи пример использования Safe Area
1.0 Junior🔥 25💬 1

Пример использования FutureBuilder

FutureBuilder — это один из самых полезных виджетов в Flutter для работы с асинхронными операциями.

Основной пример: загрузка данных пользователя

import 'package:flutter/material.dart';
Читать полностью ->
Что такое didUpdateWidget?
1.3 Junior🔥 25💬 1

didUpdateWidget: Отслеживание изменений свойств

didUpdateWidget — это важный lifecycle метод в StatefulWidget, который вызывается когда родительский виджет перестраивается и передаёт новые параметры (properties) в StatefulWidget. Это ключевой метод для реагирования на изменения входных данных.

Когда вызывается didUpdateWidget

class MyStatefulWidget extends StatefulWidget {
  final String title;  // Входное свойство
  
  const MyStatefulWidget({required this.title});
  
  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
Читать полностью ->
Что такое Future и Stream в Dart? В чём их отличия?
2.0 Middle🔥 25💬 1

Future и Stream в Dart: Полное руководство

Future и Stream — это два основных способа работы с асинхронным кодом в Dart. Они решают разные задачи и используются в зависимости от характера данных.

Future — одно значение в будущем

Future представляет результат асинхронной операции, которая произойдёт в будущем (или не произойдёт, если произойдёт ошибка). Это как обещание вернуть ровно одно значение.

// Простой Future
Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return "Hello, Future!";
}

// Использование
void main() async {
  final data = await fetchData();
  print(data); // Hello, Future!
}

// Альтернативный способ без async/await
void main() {
  fetchData().then((data) {
    print(data); // Hello, Future!
  }).catchError((error) {
    print("Error: $error");
  });
}

Состояния Future:

Читать полностью ->
Какие знаешь виды виджетов?
1.0 Junior🔥 25💬 1

Виды виджетов в Flutter

Виджет — это базовая строительная единица Flutter приложения. Каждый элемент UI (кнопка, текст, картинка) — это виджет. Flutter имеет сотни встроенных виджетов, разделённых на категории.

1. Stateless vs Stateful

StatelessWidget — виджет без состояния, неизменяемый:

class MyButton extends StatelessWidget {
  const MyButton({Key? key}) : super(key: key);

@override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => print('Clicked'),
      child: Text('Press me'),
    );
  }
}

StatefulWidget — виджет со состоянием, может меняться:

class Counter extends StatefulWidget {
  const Counter({Key? key}) : super(key: key);

@override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int count = 0;
Читать полностью ->
Что такое неявные анимации?
2.3 Middle🔥 25💬 1

Неявные анимации в Flutter

Неявные анимации — это встроенный механизм Flutter для плавного переходу между состояниями без явного управления анимационными контроллерами. Это один из самых удобных способов добавления анимаций в приложение.

Определение и основная концепция

Неявная анимация автоматически создает переход между старым и новым значением свойства, когда изменяется параметр виджета. Вместо того чтобы вручную управлять AnimationController и Ticker, Flutter сам управляет анимацией за кулисами.

Примеры неявных анимаций: TweenAnimationBuilder, AnimatedContainer, AnimatedOpacity, AnimatedPositioned, AnimatedAlign и многие другие.

Как работают неявные анимации

stateChanged()
  ↓
Change widget parameter
  ↓
Flutter detects the change
  ↓
Automatically create animation from old to new value
  ↓
Rebuild with interpolated values during animation

Пример 1: AnimatedContainer

Это самый популярный виджет для неявных анимаций.

Читать полностью ->
Какие варианты локального хранения данных есть во Flutter?
1.8 Middle🔥 24💬 2

Варианты локального хранения данных во Flutter

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

1. SharedPreferences — простые ключ-значение

SharedPreferences — это самый простой способ сохранения примитивных данных (строки, числа, булевы значения). Данные хранятся в виде ключ-значение.

import package:shared_preferences/shared_preferences.dart;

// Сохранение
final prefs = await SharedPreferences.getInstance();
await prefs.setString(username, John);
await prefs.setInt(age, 30);
await prefs.setBool(isLoggedIn, true);

// Загрузка
final String? username = prefs.getString(username);
final int? age = prefs.getInt(age);
final bool isLoggedIn = prefs.getBool(isLoggedIn) ?? false;

// Удаление
await prefs.remove(username);
Читать полностью ->
Что такое Cupertino?
1.6 Junior🔥 24💬 1

Cupertino в Flutter

Что такое Cupertino

Cupertino — это набор компонентов Flutter, которые следуют дизайн-языку Apple (iOS design language). Название происходит от Cupertino, Калифорния — место, где находится штаб-квартира Apple.

Это одна из двух основных UI библиотек в Flutter:

  • Material Design — для Android (Google)
  • Cupertino Design — для iOS (Apple)

Material vs Cupertino

// Material Design (Android-like)
import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Home')),
        body: Center(child: Text('Hello')),
        floatingActionButton: FloatingActionButton(
          onPressed: () {},
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

// Cupertino Design (iOS-like)
import 'package:flutter/cupertino.dart';
Читать полностью ->
Как организуешь взаимодействие между блоками?
2.3 Middle🔥 24💬 1

Как организуешь взаимодействие между блоками?

Взаимодействие между BLoC'ами — это критичная часть архитектуры больших Flutter приложений. Существует несколько подходов, каждый имеет свои плюсы и минусы.

1. Event-driven архитектура (рекомендуемый подход)

Один BLoC генерирует события, которые обрабатывает другой BLoC:

// UserBloc — генерирует события при изменении пользователя
class UserBloc extends Bloc<UserEvent, UserState> {
  final UserRepository userRepository;
  
  UserBloc(this.userRepository) : super(UserInitial()) {
    on<FetchUserEvent>((event, emit) async {
      emit(UserLoading());
      try {
        final user = await userRepository.getUser(event.userId);
        emit(UserLoaded(user: user));
      } catch (e) {
        emit(UserError(message: e.toString()));
      }
    });
  }
}
Читать полностью ->
Как объявить non-nullable переменную и при этом установить для нее значение?
1.2 Junior🔥 24💬 1

Как объявить non-nullable переменную и при этом установить для неё значение?

Это один из ключевых вопросов о null safety в Dart. Non-nullable переменные требуют инициализации значением, не null.

Основные способы объявления

1. Инициализация при объявлении (самый простой способ)

// ✅ Правильно - инициализируем сразу
String name = "John";
int age = 25;
bool isActive = true;
List<String> tags = ["flutter", "dart"];

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

2. Инициализация в конструкторе класса

Для полей класса это самый распространённый способ:

class User {
  late String name;  // Объявляем non-nullable
  late int age;
  
  User(this.name, this.age);  // Инициализируем в конструкторе
}

final user = User("Alice", 30);
print(user.name);  // "Alice" - гарантированно не null

Даже лучше — использовать инициализацию параметров:

Читать полностью ->
Для чего нужен AppBar?
1.3 Junior🔥 24💬 1

AppBar в Flutter: Назначение и возможности

AppBar — это один из самых важных виджетов в Flutter, который представляет собой материальный дизайн верхнюю панель приложения. Это не просто декоративный элемент, а функциональный компонент, который обеспечивает ключевые возможности для взаимодействия пользователя с приложением.

Основные функции AppBar

1. Отображение заголовка приложения AppBar служит местом для размещения названия текущего экрана или приложения. Это помогает пользователю понять, где он находится в приложении.

AppBar(
  title: Text("Мой профиль"),
)

2. Навигация AppBar автоматически добавляет кнопку "назад" (leading button) при использовании в контексте маршрутизации. Это позволяет пользователям легко вернуться на предыдущий экран.

3. Действия и меню Применять несколько кнопок действий (actions) в правой части AppBar. Это могут быть кнопки поиска, сохранения, удаления и другие операции.

Читать полностью ->
Что такое чистая архитектура?
2.0 Middle🔥 24💬 1

Чистая архитектура в Flutter

Чистая архитектура (Clean Architecture) — это подход к организации кода, разработанный Robert Martin. Цель: сделать код независимым от фреймворков, баз данных, UI и легко тестируемым.

Основные принципы

Все слои организованы как слои луковицы, где каждый слой зависит только от более внутренних:

┌─────────────────────────────────────────┐
│  Presentation (UI, State Management)    │
├─────────────────────────────────────────┤
│  Application (Use Cases, Controllers)   │
├─────────────────────────────────────────┤
│  Domain (Entities, Repository interfaces)│
├─────────────────────────────────────────┤
│  Infrastructure (API, Database)         │
└─────────────────────────────────────────┘

Слои архитектуры

Domain Layer — самый независимый слой, содержит бизнес-логику:

Читать полностью ->
Что выберешь Provider или inheritedwidget?
2.0 Middle🔥 24💬 1

Provider vs InheritedWidget

Это классический вопрос в Flutter. Оба решения работают для передачи данных вниз по дереву виджетов, но выбор зависит от контекста и требований проекта.

Коротко: что выберу я

Я выберу Provider практически всегда. Вот почему: Provider построен на InheritedWidget и предоставляет удобный API, лучшую производительность, переиспользуемость и ecosystem пакетов.

Но давайте разберёмся подробнее.

InheritedWidget — низкоуровневый инструмент

InheritedWidget — это базовый механизм Flutter для передачи данных:

class MyData extends InheritedWidget {
  final String value;

MyData({
    required this.value,
    required Widget child,
  }) : super(child: child);

@override
  bool updateShouldNotify(MyData oldWidget) {
    return oldWidget.value != value;
  }

static MyData? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyData>();
  }
}

// Использование
MyData.of(context)?.value
Читать полностью ->
Расскажи про структуры данных
1.3 Junior🔥 24💬 1

Расскажи про структуры данных

Это важный вопрос для Flutter разработчика. Расскажи про структуры данных включает в себя несколько ключевых аспектов, которые я понимаю и могу объяснить.

Основные концепции

Вопрос касается важной части разработки на Flutter и требует глубокого понимания фреймворка.

Практическое применение

В реальных проектах часто используются эти концепции для создания эффективного и масштабируемого кода.

Лучшие практики

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

Читать полностью ->
Как приоритезируешь задачи?
1.0 Junior🔥 24💬 1

Приоритизация задач: системный подход разработчика

Мой процесс приоритизации

Я использую комбинацию методов для эффективной приоритизации, потому что разные типы задач требуют разного подхода. Это помогает балансировать между срочностью, важностью и долгосрочной ценностью проекта.

1. Матрица Eisenhower (Срочность × Важность)

┌─────────────────────────┬──────────────────────┐
│  ВАЖНО + СРОЧНО         │  ВАЖНО + НЕ СРОЧНО   │
│  (Do First)             │  (Schedule)          │
│  - Production bugs      │  - Рефакторинг       │
│  - Критичные features   │  - Оптимизация       │
│  - Security issues      │  - Документация      │
├─────────────────────────┼──────────────────────┤
│  НЕ ВАЖНО + СРОЧНО      │  НЕ ВАЖНО + НЕ СР.   │
│  (Delegate/Minimize)    │  (Eliminate)         │
│  - Срочные запросы      │  - Nice-to-have      │
│  - Текущие проблемы     │  - Золотое покрытие  │
└─────────────────────────┴──────────────────────┘

2. Оценка влияния и затрат

Читать полностью ->
Какие знаешь деревья в Flutter?
1.2 Junior🔥 24💬 1

Деревья в Flutter

В Flutter существует несколько типов деревьев, каждое отвечает за разную часть архитектуры приложения.

1. Widget Tree

Это логическое описание UI структуры:

MyApp()
├── MaterialApp
│   └── Scaffold
│       ├── AppBar
│       └── Body

Stроится в методе build() и пересчитывается при каждом обновлении.

2. Element Tree

Внутреннее представление Widget Tree. Элементы управляют жизненным циклом виджетов:

  • Widget — immutable (неизменяемый)
  • Element — mutable, живет дольше чем Widget

3. Render Tree

Самый низкий уровень — RenderObject's:

RenderBox (Scaffold)
├── RenderAppBar
├── RenderColumn
│   ├── RenderImage
│   └── RenderText

Отвечает за:

  • Layout — вычисляет размеры и позиции
  • Painting — рисует на canvas
  • Hit testing — определяет какой widget был таппнут

4. BuildContext Tree

Связь между Widget и Element:

Читать полностью ->
Для чего нужен StatefulWidget?
1.0 Junior🔥 24💬 1

StatefulWidget — основной паттерн для изменяемого состояния

StatefulWidget — это базовый класс в Flutter для создания виджетов, которые могут менять своё состояние в процессе жизненного цикла приложения. В отличие от StatelessWidget, который рендерится один раз и не обновляется, StatefulWidget позволяет отслеживать и обновлять данные в реальном времени.

Основные назначения StatefulWidget

1. Управление изменяемым состоянием

  • Хранение данных, которые могут измениться (текст в TextField, значение счётчика, флаги toggle)
  • Реактивное обновление UI при изменении этих данных
  • Вызов метода setState() для пересчёта виджета
class Counter extends StatefulWidget {
  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int count = 0;

void increment() {
    setState(() {
      count++;
    });
  }

@override
  Widget build(BuildContext context) {
    return Text(count.toString());
  }
}
Читать полностью ->
Является ли Flutter однопоточным?
1.0 Junior🔥 23💬 2

Является ли Flutter однопоточным?

Да, Flutter использует однопоточную архитектуру на основе модели событий. Это важный концепт, который нужно понимать для эффективной разработки.

Архитектура Flutter

Flutter построен на Event Loop (цикл событий), подобно JavaScript:

Flutter Engine
├── UI Thread (Main Isolate)
│   ├── Event Queue
│   ├── Microtask Queue
│   └── Render Loop (60-120 FPS)
├── I/O Thread
├── GPU Thread
└── Platform Channels (Native)

Main Isolate — это основной поток, где выполняется весь Dart код приложения.

Как это работает

  1. Event Loop обрабатывает события в очередности:

    • Микротаски (microtasks) из Dart
    • Обычные события (UI, асинхронные операции)
  2. Rendering происходит после обработки события:

    • Перестройка виджетов
    • Новая сцена отправляется GPU
Читать полностью ->
Что такое паттерн Singleton?
2.2 Middle🔥 23💬 2

Singleton паттерн — единственный экземпляр класса

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

Основная идея

Singleton используется когда:

  • Нужен только один экземпляр — база данных, логгер, конфигурация
  • Глобальная точка доступа — все части приложения используют один объект
  • Ленивая инициализация — объект создается при первом обращении
  • Потокобезопасность — гарантированная безопасность в многопоточной среде

Простая реализация в Dart

class Database {
  // Приватный конструктор
  Database._internal();

// Статический экземпляр
  static Database? _instance;

// Фабричный конструктор
  factory Database() {
    // Ленивая инициализация
    _instance ??= Database._internal();
    return _instance!;
  }

void connect() {
    print('Database connected');
  }
}
Читать полностью ->
По каким критериям выбираешь архитектуру?
3.0 Senior🔥 23💬 1

По каким критериям выбираю архитектуру

Выбор архитектуры — это не просто техническое решение, а стратегическое. Я смотрю на несколько факторов, чтобы сделать правильный выбор.

1. Размер и сложность проекта

Маленькое приложение (< 10 экранов, < 20k строк кода)

// Подойдёт простая архитектура
// Stateful widgets + Provider + ValueNotifier

class CounterScreen extends StatefulWidget { ... }
class CounterProvider extends ChangeNotifier { ... }

final counterProvider = ChangeNotifierProvider(
  (ref) => CounterProvider(),
);

Оверинжиниринг с BLoC здесь не нужен.

Среднее приложение (10-50 экранов, 50-200k строк)

// Подойдёт Provider или Riverpod
// Чистая архитектура без излишеств

final userProvider = FutureProvider((ref) async {
  return ref.watch(userRepositoryProvider).getUser();
});

Баланс между простотой и структурированностью.

Большое приложение (> 50 экранов, > 200k строк)

Читать полностью ->
Какие знаешь библиотеки для хранения данных?
2.0 Middle🔥 23💬 1

Какие знаешь библиотеки для хранения данных

В Flutter существует множество библиотек для хранения данных на разных уровнях: от простого кеша до полнофункциональных баз данных. Рассмотрю самые популярные и полезные.

1. SharedPreferences — простое хранилище

Для: Простые данные (строки, числа, булевы значения)

import 'package:shared_preferences/shared_preferences.dart';

class UserPreferences {
  static const _themeKey = 'theme';
  
  static Future<void> saveTheme(String theme) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_themeKey, theme);
  }
  
  static Future<String?> getTheme() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(_themeKey);
  }
}

Плюсы:

  • Простая в использовании
  • Встроенная синхронизация
  • Быстрая

Минусы:

  • Только примитивные типы
  • Не подходит для сложных данных

2. Hive — быстрая NoSQL БД

Читать полностью ->
Как работает метод setState?
2.0 Middle🔥 23💬 1

setState в Flutter: Как работает механизм обновления состояния

setState — одна из самых используемых функций в Flutter, но многие разработчики не понимают, как она работает под капотом. Это не просто "пересчитай виджет" — это сложный механизм, связанный с жизненным циклом и сборкой кадров.

1. Что делает setState?

setState() — это метод State класса, который:

  1. Вызывает переданный callback (где ты меняешь переменные)
  2. Помечает виджет как "dirty" (грязный - требует перестроения)
  3. Запускает пересборку дерева виджетов
class CounterWidget extends StatefulWidget {
  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int counter = 0;

void increment() {
    setState(() {
      counter++; // Меняешь состояние
    });
    // После блока setState() запускается перестроение
  }

@override
  Widget build(BuildContext context) {
    return Text('Counter: $counter');
  }
}
Читать полностью ->