Меня зовут Тимур, я Senior Frontend Developer, TeamLead и ментор.
Успешно разработал и вывел в эксплуатацию 5 продуктов с нуля.
Три в Сбербанке (Продукт года ежегодной премии Digital Leaders)
Два в продуктовой компании.
Менторю с лета 2022.
Мой стек: TypeScript, React, Vue3
Помогаю людям с любым уровнем знаний стать разработчиками с зп от 200к
Менторство && Отзывы
Роадмап с нуля до джуна
https://miro.com/app/board/uXjVMXKy4gQ=/
https://easydev.yonote.ru/share/cources-accounts
Я выкинул все лишнее, остается только то что понадобится для реальной работы над проектом, если нужен аккаунт с курсами из роадмапа пишите в лс бесплатно выдам
Успешно разработал и вывел в эксплуатацию 5 продуктов с нуля.
Три в Сбербанке (Продукт года ежегодной премии Digital Leaders)
Два в продуктовой компании.
Менторю с лета 2022.
Мой стек: TypeScript, React, Vue3
Помогаю людям с любым уровнем знаний стать разработчиками с зп от 200к
Менторство && Отзывы
Роадмап с нуля до джуна
https://miro.com/app/board/uXjVMXKy4gQ=/
https://easydev.yonote.ru/share/cources-accounts
Я выкинул все лишнее, остается только то что понадобится для реальной работы над проектом, если нужен аккаунт с курсами из роадмапа пишите в лс бесплатно выдам
👍4🔥2✍1
Forwarded from Тимур Селедков
#доклад #навыки
Как сделать сложную таску?
https://easydev.yonote.ru/share/skill-how-make-hard-task
Когда задачу можно назвать сложной?
Выделю три типа "сложных" задач:
1.Недостаточно вводных данных
Пример: У Васи задача “сделать поиск как в гугле”
Чеклист:
- есть тз?
- есть апи?
- есть макет?
Решение: уточняем вводные данные, у кого?
мой видос по воркфлоу, определяем чья зона ответственности, понимаем кому написать, ответы крепим к задаче комментами или в описание самой задачи
2. Объемная
Пример: сделать редизайн всего приложения
Решение?
разбиваем на подзадачи по блокам или функциональности
например:
- сделать редизайн страницы регистрации и авторизации
- сделать редизайн главного меню
- сделать редизайн страницы А
- сделать редизайн страницы Б
3. У нас нет точного представления как ее сделать
Например: “Сделать страницу поиска как в Google”
Типовые проблемы:
- Непонятно с чего начинать
- Пробуем делать все сразу, постоянно переключаемся из-за чего мы тратим много энергии, при этом темп работы выходит низкий, а результата не видно
Решение:
а) Приоритезация
- Разбиваем задачу на функционал, ориентируемся на юзер стори
Например: “сделать поиск и вывести результаты” это минимальный полезный функционал, самых важных 1-3 юзер стори
b) Декомпозиция
- Разбиваем приоритетную задачу до тех пор пока не будет понятно как ее сделать за конечное время, за условных 1-2часа
Например:
b.1) “сделать поиск”
- ввод текста
- отправка текста на бэк и получение результата
b.2) сделать вывод результатов
- сделать компонент выводимого результата
- разложить полученные данные по компонентам
b.3) сделать переход на страницы найденных результатов
- сделать у компонента результата кликабельную ссылку с переходом
c) Реализация
- Садимся и делаем первую задачу с проведенной декомпозиции и СТРОГО только ее!!!
- реализуем следующую одну за другой
Следующая итерация с пункта 3.а
Какая польза использования данного подхода?
1) когда мы видим простую и понятную задачу ее легче начать делать, а значит и сделать
2) закрывая много маленьких задач наш мозг получает постоянное позитивное подкрепление
3) закрывая подзадачи мы видим прогресс выполнения нашей большой задачи и мы знаем что сказать на дейлики и можем спрогнозировать сроки
4) при решении понятных задач наш мозг меньше устает и его ресурса дольше хватает
Лайфхаки работающие у меня:
- дневной сон
- прогулка без девайсов
- рабочие сессии по 2-3 часа
- помидорро
- тайм блокинг
Как сделать сложную таску?
https://easydev.yonote.ru/share/skill-how-make-hard-task
Когда задачу можно назвать сложной?
Выделю три типа "сложных" задач:
1.Недостаточно вводных данных
Пример: У Васи задача “сделать поиск как в гугле”
Чеклист:
- есть тз?
- есть апи?
- есть макет?
Решение: уточняем вводные данные, у кого?
мой видос по воркфлоу, определяем чья зона ответственности, понимаем кому написать, ответы крепим к задаче комментами или в описание самой задачи
2. Объемная
Пример: сделать редизайн всего приложения
Решение?
разбиваем на подзадачи по блокам или функциональности
например:
- сделать редизайн страницы регистрации и авторизации
- сделать редизайн главного меню
- сделать редизайн страницы А
- сделать редизайн страницы Б
3. У нас нет точного представления как ее сделать
Например: “Сделать страницу поиска как в Google”
Типовые проблемы:
- Непонятно с чего начинать
- Пробуем делать все сразу, постоянно переключаемся из-за чего мы тратим много энергии, при этом темп работы выходит низкий, а результата не видно
Решение:
а) Приоритезация
- Разбиваем задачу на функционал, ориентируемся на юзер стори
Например: “сделать поиск и вывести результаты” это минимальный полезный функционал, самых важных 1-3 юзер стори
b) Декомпозиция
- Разбиваем приоритетную задачу до тех пор пока не будет понятно как ее сделать за конечное время, за условных 1-2часа
Например:
b.1) “сделать поиск”
- ввод текста
- отправка текста на бэк и получение результата
b.2) сделать вывод результатов
- сделать компонент выводимого результата
- разложить полученные данные по компонентам
b.3) сделать переход на страницы найденных результатов
- сделать у компонента результата кликабельную ссылку с переходом
c) Реализация
- Садимся и делаем первую задачу с проведенной декомпозиции и СТРОГО только ее!!!
- реализуем следующую одну за другой
Следующая итерация с пункта 3.а
Какая польза использования данного подхода?
1) когда мы видим простую и понятную задачу ее легче начать делать, а значит и сделать
2) закрывая много маленьких задач наш мозг получает постоянное позитивное подкрепление
3) закрывая подзадачи мы видим прогресс выполнения нашей большой задачи и мы знаем что сказать на дейлики и можем спрогнозировать сроки
4) при решении понятных задач наш мозг меньше устает и его ресурса дольше хватает
Лайфхаки работающие у меня:
- дневной сон
- прогулка без девайсов
- рабочие сессии по 2-3 часа
- помидорро
- тайм блокинг
YouTube
Как сделать сложную таску?
Доведение до трудоустройства фронтенд разработчиком с любого уровня мой сайт - easydev.club
Таймкоды:
00:00 - Виды сложных задач
00:33 — Первый тип и решение: недостаточно вводных данных
03:26 — Второй тип и решение: объемная задача
04:45 — Третий тип и…
Таймкоды:
00:00 - Виды сложных задач
00:33 — Первый тип и решение: недостаточно вводных данных
03:26 — Второй тип и решение: объемная задача
04:45 — Третий тип и…
🔥7✍3👍3❤2⚡1❤🔥1🕊1🍓1💘1
На собеседеованиях один из самых частых вопросов по TypeScript - чем type отличается от interface?
Давайте разбираться:
1️⃣ Для каких структур предназначен
Interface преднаначен для описания структур объектов
type универсален и может описывать не только структуры объектов, но и примитивные типы, объединение и др
2️⃣ Объединения (Union)
type умеет а interface нет
3️⃣ Расширение
type расширяется через & (intersection)
interface через ключевое слово extends
4️⃣ Слияние деклараций
Интерфейсы поддерживают слияние деклараций, что позволяет определять несколько интерфейсов с одинаковым именем, которые TypeScript объединит в один:
лично я считаю это плохой практикой и всегда говорю об этом на собеседовании
для type такое не поддерживается и выпадет ошибка что такое имя типа уже используется
5️⃣ Классы и interface:
Классы могут реализовывать interface с помощью ключевого слова implements.
В случае с type можно имплеменитровать его только если он в виде описания объекта или пересечения объектов.
Нельзя с примитивом или объединением(union)
Менторство && Отзывы
Давайте разбираться:
Interface преднаначен для описания структур объектов
interface User {
name: string;
age: number;
}
type универсален и может описывать не только структуры объектов, но и примитивные типы, объединение и др
type User = {
name: string;
age: number;
};
type SerialCode = string
type умеет а interface нет
type TypeAorB = TypeA | TypeB;
type ID = number | string
type TaskStatus = 'todo' | 'processed' | 'done' | 'testing';
type расширяется через & (intersection)
type TypeAandB = TypeA & TypeB;
interface через ключевое слово extends
interface IAandB extends IA, IB {}
Интерфейсы поддерживают слияние деклараций, что позволяет определять несколько интерфейсов с одинаковым именем, которые TypeScript объединит в один:
лично я считаю это плохой практикой и всегда говорю об этом на собеседовании
interface IA {
name: string;
}
interface IA {
age: number;
}
// в результате будет так:
interface IA {
name: string;
age: number;
}
для type такое не поддерживается и выпадет ошибка что такое имя типа уже используется
Классы могут реализовывать interface с помощью ключевого слова implements.
interface IA {
name: string;
}
class Cat implements IA {
name: string;
constructor(name: string) {
this.name = name;
}
}
В случае с type можно имплеменитровать его только если он в виде описания объекта или пересечения объектов.
Нельзя с примитивом или объединением(union)
type Text = string;
class Example implements Text { }
// Ошибка: A class can only implement an object type or intersection of object types with statically known members
type Shape = Circle | Square;
class Figure implements Shape { }
// Ошибка A class can only implement an object type or intersection of object types with statically known members
// описание объекта
type Identifiable = {
id: number | string // тут можно union тк описывается ключ объекта
};
// пересечение объектов
type UserType = Identifiable & {
name: string;
age: number;
};
// Все хорошо
class User implements UserType {
id: number | string;
name: string;
age: number;
constructor(id: number, name: string, age: number) {
this.id = id;
this.name = name;
this.age = age;
}
}
Менторство && Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18❤4👍4
Качаем frontend бицуху - как обновлять данные в UI, если мы их меняем на сервере ⁉️
Ниже три стратегии обновления данных, каждая с описанием, её ключевой ценностью и примером использования.
⚡ 1. Оптимистичное (позитивное) обновление
Описание:
UI мгновенно отражает изменение, не дожидаясь ответа сервера. Запрос отправляется «в фоне», а интерфейс уже показывает результат. При ошибке происходит «откат» назад и выводится уведомление.
В чем фишка:
* Мгновенная реакция приложения — пользователь не видит задержек и получает «живой» отклик.
* Снижение ощущаемой латентности, особенно важно в высокоинтерактивных сценариях.
* Простота UX — нет «зависшего» состояния ожидания.
Рассмотрим на примере: «лайк котиков в соцсети»
1. Пользователь кликает «лайк» у фотографии кота.
2. Счётчик лайков тут же увеличивается в интерфейсе (+1).
3. В фоне отправляется запрос:
4. Если сервер вернёт 200 OK — ничего не меняем.
5. Если ошибка — возвращаем счётчик на прежнее значение и показываем сообщение «Не удалось поставить лайк».
⏳2. Пассивное (рефетч после мутации) обновление
Описание:
UI меняет данные только после подтверждения от сервера. Сначала отправляется запрос на изменение, затем, получив успешный ответ и (опционально) тело с обновлёнными данными, интерфейс обновляется.
В чем фишка:
* Гарантия консистентности локального состояния с серверным.
* Нет необходимости писать логику «отката» — изменения применяются только после «200 OK».
* Меньше лишних запросов, чем при полном рефетче всего списка.
Рассмотрим на примере: «локальный ToDo-список»
1. Пользователь редактирует задачу и нажимает «Сохранить».
2. Отправляется запрос:
3. Ожидаем ответа сервера.
4. Если пришёл 200 OK с телом обновлённой задачи — заменяем запись в локальном списке. (если апишка не возвращает обновленные данные то делаем перезапрос этой сущности по ид и ее пихаем в стейт)
5. При ошибке (400/500 или сбое сети) — оставляем старое состояние и выводим «Не удалось сохранить задачу».
🌐 3. Серверное (рефетч всего списка) обновление
Описание:
После выполнения операции приложение полностью перезапрашивает релевантные данные (весь список или следующую запись), чтобы синхронизироваться с текущим состоянием сервера.
В чем фишка:
* Максимальная актуальность — вы точно знаете текущее состояние всей очереди или каталога.
* Избежание рассинхрона в многопользовательских сценариях, где многие участники параллельно меняют одни и те же данные.
* Упрощённая логика обработки конфликтов — нет «частичных» обновлений.
Рассмотрим на примере:: «Таск-трекер» Или «Сервис Доставки»
1. Курьер нажимает «Выполнено» на задаче.
2. Отправляется запрос:
3. После 200 OK сразу выполняется дополнительный запрос:
4. Полученные данные (следующая задача или весь актуальный список) полностью заменяют локальную очередь.
5. При ошибке любого из запросов — выводится сообщение об ошибке и предлагается повторить операцию.
---
Вывод:
Все три стратегии нормальны и имеют право на жизнь. Выбирайте в зависимости от конкретного бизнес-кейса:
⚡Оптимистичное — для мгновенных реакций (лайки, быстрые клики, чат).
⏳ Пассивное — для CRUD-форм, когда важно применять изменения только после подтверждения и мы работает с одним элементом (профиль / страница заказа) или целевое использование приложения подразумевает что пользователь работает только со своим набором елементов.
🌐 Серверное — для многопользовательских систем (заказы, таск-менеджмент), где критична абсолютная консистентность, чтобы видеть самую актуальную информацию.
Менторство && Отзывы
Ниже три стратегии обновления данных, каждая с описанием, её ключевой ценностью и примером использования.
⚡ 1. Оптимистичное (позитивное) обновление
Описание:
UI мгновенно отражает изменение, не дожидаясь ответа сервера. Запрос отправляется «в фоне», а интерфейс уже показывает результат. При ошибке происходит «откат» назад и выводится уведомление.
В чем фишка:
* Мгновенная реакция приложения — пользователь не видит задержек и получает «живой» отклик.
* Снижение ощущаемой латентности, особенно важно в высокоинтерактивных сценариях.
* Простота UX — нет «зависшего» состояния ожидания.
Рассмотрим на примере: «лайк котиков в соцсети»
1. Пользователь кликает «лайк» у фотографии кота.
2. Счётчик лайков тут же увеличивается в интерфейсе (+1).
3. В фоне отправляется запрос:
POST /cats/{catId}/like
4. Если сервер вернёт 200 OK — ничего не меняем.
5. Если ошибка — возвращаем счётчик на прежнее значение и показываем сообщение «Не удалось поставить лайк».
⏳2. Пассивное (рефетч после мутации) обновление
Описание:
UI меняет данные только после подтверждения от сервера. Сначала отправляется запрос на изменение, затем, получив успешный ответ и (опционально) тело с обновлёнными данными, интерфейс обновляется.
В чем фишка:
* Гарантия консистентности локального состояния с серверным.
* Нет необходимости писать логику «отката» — изменения применяются только после «200 OK».
* Меньше лишних запросов, чем при полном рефетче всего списка.
Рассмотрим на примере: «локальный ToDo-список»
1. Пользователь редактирует задачу и нажимает «Сохранить».
2. Отправляется запрос:
PUT /todos/{todoId}
3. Ожидаем ответа сервера.
4. Если пришёл 200 OK с телом обновлённой задачи — заменяем запись в локальном списке. (если апишка не возвращает обновленные данные то делаем перезапрос этой сущности по ид и ее пихаем в стейт)
5. При ошибке (400/500 или сбое сети) — оставляем старое состояние и выводим «Не удалось сохранить задачу».
🌐 3. Серверное (рефетч всего списка) обновление
Описание:
После выполнения операции приложение полностью перезапрашивает релевантные данные (весь список или следующую запись), чтобы синхронизироваться с текущим состоянием сервера.
В чем фишка:
* Максимальная актуальность — вы точно знаете текущее состояние всей очереди или каталога.
* Избежание рассинхрона в многопользовательских сценариях, где многие участники параллельно меняют одни и те же данные.
* Упрощённая логика обработки конфликтов — нет «частичных» обновлений.
Рассмотрим на примере:: «Таск-трекер» Или «Сервис Доставки»
1. Курьер нажимает «Выполнено» на задаче.
2. Отправляется запрос:
PUT /todos/{todoId}
3. После 200 OK сразу выполняется дополнительный запрос:
GET /tasks
4. Полученные данные (следующая задача или весь актуальный список) полностью заменяют локальную очередь.
5. При ошибке любого из запросов — выводится сообщение об ошибке и предлагается повторить операцию.
---
Вывод:
Все три стратегии нормальны и имеют право на жизнь. Выбирайте в зависимости от конкретного бизнес-кейса:
⚡Оптимистичное — для мгновенных реакций (лайки, быстрые клики, чат).
⏳ Пассивное — для CRUD-форм, когда важно применять изменения только после подтверждения и мы работает с одним элементом (профиль / страница заказа) или целевое использование приложения подразумевает что пользователь работает только со своим набором елементов.
🌐 Серверное — для многопользовательских систем (заказы, таск-менеджмент), где критична абсолютная консистентность, чтобы видеть самую актуальную информацию.
Менторство && Отзывы
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍4😁2❤1