Урок 49 из 49 · Месяц 6. TypeScript и выход на работу
Завершение проекта и подготовка к собеседованию
Содержание урока
- Завершение проекта
- Чек-лист готового проекта
- README, который читают
- Резюме и портфолио
- Резюме junior-фронтендера
- GitHub как портфолио
- Частые вопросы на собеседовании
- HTML и CSS
- JavaScript
- React
- TypeScript
- Общие вопросы
- Лайвкодинг
- Задача 1. Уникальные значения
- Задача 2. Палиндром
- Задача 3. Подсчёт символов
- Задача 4. React: поиск по списку
- Финальный экзамен
- Что нужно уметь
- Пример контрольной работы
- Советы по подготовке
- Практика
- Итоги
Это финальный урок курса: за полгода вы прошли путь от первого тега до React-приложения на TypeScript. Осталось довести проекты до состояния «не стыдно показать», собрать резюме и портфолио, повторить вопросы, которые чаще всего задают junior-фронтендерам, и подготовиться к финальному экзамену. Здесь собраны чек-листы, короткие ответы на частые вопросы и примеры задач для лайвкодинга.
Завершение проекта
Работодатель смотрит не на количество проектов, а на то, насколько они законченные. Один аккуратный проект лучше пяти брошенных на середине.
Чек-лист готового проекта
- Проект задеплоен и открывается по ссылке (Vercel, Netlify, GitHub Pages или другой хостинг).
- Работает на телефоне: проверено на ширине 375px (урок Tailwind CSS и адаптивная вёрстка).
- Есть состояния загрузки, ошибки и пустого списка.
- Нет ошибок в консоли браузера и в
npm run build. - Нет секретов в репозитории:
.envв.gitignore, в README — пример.env.example. - Понятная структура папок (урок Архитектура проектов).
- Осмысленные коммиты, а не десять коммитов «fix».
- Есть README.
README, который читают
README — это обложка проекта. Работодатель открывает его первым.
# Shop — интернет-магазин электроники
Демо: https://your-shop.example.com
Каталог с фильтрами и поиском, корзина, авторизация по JWT.
## Стек
React 19, TypeScript, Vite, TanStack Query, Zustand, React Router, Tailwind CSS
## Возможности
- фильтрация и сортировка через query-параметры
- корзина сохраняется после перезагрузки
- регистрация и вход, защищённые маршруты
- адаптивная вёрстка от 375px
## Запуск
npm install
cp .env.example .env
npm run dev
Добавьте 1–2 скриншота или короткую GIF-анимацию работы приложения — так проект понятен за 10 секунд.
Резюме и портфолио
Резюме junior-фронтендера
Одна страница, без лишнего. Структура:
- Имя, позиция — «Frontend-разработчик (React, TypeScript)».
- Контакты — Telegram, почта, GitHub, ссылка на портфолио.
- Навыки — только то, что можете объяснить на собеседовании: HTML, CSS, Tailwind, JavaScript, TypeScript, React, React Router, TanStack Query, Zustand, react-hook-form, Git, REST API.
- Проекты — 2–4 лучших: название, одна строка о проекте, стек, что сделали лично вы, ссылки на демо и код.
- Опыт — если есть (даже не IT: ответственность и работа в команде тоже ценятся).
- Образование и курсы.
Пример описания проекта:
Shop — интернет-магазин электроники
React, TypeScript, TanStack Query, Zustand, Tailwind
• Каталог с фильтрацией, сортировкой и пагинацией через query-параметры
• Авторизация по JWT, защищённые маршруты, обновление токена
• Типы API сгенерированы из Swagger (Orval)
Демо: ... · Код: ...
GitHub как портфолио
- Закрепите (Pin) лучшие репозитории на главной странице профиля.
- У каждого — описание, ссылка на демо и README.
- Удалите или сделайте приватными учебные «пробы» без README.
- Зелёные квадратики активности — плюс, но качество кода важнее.
Частые вопросы на собеседовании
Ниже — короткие ответы. На собеседовании говорите своими словами и добавляйте пример из своего проекта.
HTML и CSS
Что такое семантическая вёрстка? Использование тегов по смыслу: header, nav, main, article, footer, button. Помогает SEO, доступности и читаемости кода.
Блочная модель? Элемент = контент + padding + border + margin. При box-sizing: border-box ширина включает padding и border.
Чем отличаются position: relative, absolute, fixed, sticky? relative — смещение от своего места; absolute — относительно ближайшего позиционированного предка; fixed — относительно окна; sticky — «прилипает» при прокрутке.
Flexbox или Grid? Flex — раскладка в одном направлении (строка или колонка), Grid — двумерная сетка (строки и колонки сразу).
Как сделать адаптивную вёрстку? Медиазапросы, относительные единицы (rem, %, vw), flex/grid, подход mobile-first.
Специфичность селекторов? Приоритет: !important > инлайн-стиль > #id > .class, [attr], :hover > тег. При равной специфичности побеждает правило ниже.
JavaScript
let, const, var? var — функциональная область видимости и всплытие; let и const — блочная область, const нельзя переприсвоить (но объект внутри менять можно).
== и ===? == приводит типы ("5" == 5 → true), === сравнивает без приведения. Используем ===.
Что такое замыкание? Функция, которая помнит переменные из места, где была создана, даже после того, как внешняя функция завершилась.
Как работает Event Loop? JS однопоточный. Синхронный код выполняется в стеке вызовов, асинхронные колбэки ждут в очередях: сначала выполняются микрозадачи (промисы), потом макрозадачи (setTimeout, события).
Что выведет код?
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);
// 1, 4, 3, 2
Promise и async/await? Promise — объект будущего результата (pending → fulfilled/rejected). async/await — более удобная запись работы с промисами; ошибки ловим через try/catch.
map, filter, reduce, forEach? map — новый массив преобразованных элементов, filter — отфильтрованный, reduce — сводит к одному значению, forEach — просто перебор, ничего не возвращает.
Копирование объектов? Spread { ...obj } делает поверхностную копию; для глубокой — structuredClone(obj).
React
Что такое Virtual DOM? Лёгкое представление интерфейса в памяти. React сравнивает новое и старое дерево и меняет в настоящем DOM только то, что изменилось.
Пропсы и состояние? Пропсы передаёт родитель, компонент их не меняет. Состояние (useState) — внутренние данные компонента; при изменении компонент перерисовывается.
Зачем key в списках? Чтобы React понимал, какой элемент добавлен, удалён или перемещён. Ключ — стабильный уникальный id, не индекс массива, если список меняется.
Как работает useEffect? Запускает побочный эффект после отрисовки. Массив зависимостей: [] — один раз после монтирования, [a] — при изменении a, без массива — после каждого рендера. Функция-возврат — очистка.
useMemo и useCallback? useMemo запоминает результат вычисления, useCallback — саму функцию. Нужны против лишних пересчётов и ререндеров, но не везде.
Как передать данные между далёкими компонентами? Поднять состояние, Context, менеджер состояния (Zustand), а данные с сервера — через TanStack Query.
Зачем TanStack Query, если есть useEffect + fetch? Кэш, повторные запросы, состояния загрузки и ошибки, инвалидация после мутаций — без ручного кода.
TypeScript
Зачем TypeScript? Ошибки видны до запуска, автодополнение, безопасный рефакторинг, код документирует сам себя.
type или interface? Оба описывают объекты. interface расширяется через extends и может объявляться повторно, type умеет union, кортежи и примитивы.
any и unknown? any отключает проверку, unknown требует проверить тип перед использованием.
Что такое generic? Тип-параметр: одна функция или тип работает с разными данными без потери типизации — function first<T>(arr: T[]): T | undefined.
Utility types? Partial, Pick, Omit, Record — создают новые типы на основе существующих.
Общие вопросы
Что происходит, когда вводишь адрес в браузере? DNS находит IP сервера, устанавливается соединение (HTTPS), браузер отправляет запрос, получает HTML, разбирает его, загружает CSS и JS, строит DOM и отрисовывает страницу.
HTTP-методы и коды? GET — получить, POST — создать, PUT/PATCH — обновить, DELETE — удалить. 2xx — успех, 4xx — ошибка клиента (400, 401, 403, 404), 5xx — ошибка сервера.
Где хранить токен? Варианты: память приложения, localStorage (просто, но уязвим к XSS), httpOnly-cookie (недоступна из JS). Хороший ответ — назвать плюсы и минусы.
Лайвкодинг
Лайвкодинг — задача, которую решаете при интервьюере, обычно 20–40 минут. Важен не только ответ, но и то, как вы думаете.
Алгоритм:
- Повторите задачу своими словами и уточните условия.
- Разберите пример вход → выход.
- Проговорите решение, прежде чем писать.
- Напишите простое рабочее решение, потом улучшайте.
- Проверьте на граничных случаях: пустой массив, одна буква,
null.
Задача 1. Уникальные значения
function unique(arr) {
return [...new Set(arr)];
}
console.log(unique([1, 2, 2, 3, 1])); // [1, 2, 3]
Set хранит только уникальные значения, spread превращает его обратно в массив.
Задача 2. Палиндром
function isPalindrome(str) {
const clean = str.toLowerCase().replace(/[^a-zа-яё0-9]/g, "");
return clean === [...clean].reverse().join("");
}
console.log(isPalindrome("А роза упала на лапу Азора")); // true
Задача 3. Подсчёт символов
function countChars(str) {
const result = {};
for (const char of str) {
result[char] = (result[char] ?? 0) + 1;
}
return result;
}
console.log(countChars("hello")); // { h: 1, e: 1, l: 2, o: 1 }
Задача 4. React: поиск по списку
import { useState } from "react";
const fruits = ["Яблоко", "Банан", "Апельсин", "Груша"];
export function FruitSearch() {
const [query, setQuery] = useState("");
const filtered = fruits.filter((f) => f.toLowerCase().includes(query.toLowerCase()));
return (
<div>
<input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Поиск" />
{filtered.length === 0 ? (
<p>Ничего не найдено</p>
) : (
<ul>
{filtered.map((f) => (
<li key={f}>{f}</li>
))}
</ul>
)}
</div>
);
}
Обратите внимание: отфильтрованный список вычисляется из query, а не хранится в отдельном useState — так нет рассинхронизации.
Финальный экзамен
Формат, сроки и критерии оценки финального экзамена уточните у менторов. Обычно итоговая проверка включает теоретические вопросы, практическое задание и защиту своего проекта.
Что нужно уметь
- Сверстать адаптивную страницу по макету (семантика, flex/grid, mobile-first, Tailwind или CSS Modules).
- Писать на JavaScript: массивы и методы перебора, деструктуризация, промисы,
async/await, обработка ошибок. - Создать React-проект на Vite с TypeScript, типизировать пропсы, состояние и события.
- Настроить маршрутизацию на React Router, параметры и защищённые страницы.
- Получать и отправлять данные через TanStack Query (
useQuery,useMutation), инвалидировать кэш. - Хранить глобальное состояние в Zustand.
- Делать формы на react-hook-form с валидацией.
- Работать с JWT-авторизацией и читать Swagger.
- Объяснить архитектуру своего проекта и принятые решения.
- Работать с Git: ветки, коммиты, pull request.
Пример контрольной работы
- Теория (устно). Три вопроса из списка выше: например, Event Loop,
useEffectи его зависимости, разницаtypeиinterface. - JavaScript. Напишите функцию
groupBy(users, "city"), которая группирует массив объектов по полю. Ожидаемый результат:{ "Бишкек": [...], "Ош": [...] }. - React + TypeScript. Сделайте страницу списка задач: загрузка через
useQuery, добавление черезuseMutation, фильтр «все / выполненные / активные». Ожидаемый результат: после добавления список обновляется без перезагрузки страницы. - Вёрстка. Карточка товара по описанию: на телефоне — колонка, от 768px — картинка слева, текст справа.
- Защита проекта. 5–7 минут: что за проект, стек, архитектура, самая сложная задача и как вы её решили.
Советы по подготовке
- Повторяйте по плану: неделя на HTML/CSS/JS, неделя на React и TypeScript.
- Решайте по 2–3 небольшие задачи в день без ИИ и подсказок (урок ИИ в разработке объясняет, почему).
- Рассказывайте ответы вслух — другу, в зеркало, на диктофон.
- Устройте пробное собеседование с одногруппником: один спрашивает, другой отвечает, потом меняетесь.
- Подготовьте рассказ о проекте заранее и отрепетируйте его по времени.
- Высыпайтесь перед экзаменом — свежая голова решает быстрее.
Практика
- Аудит проекта. Пройдите чек-лист «готового проекта» по своему лучшему проекту и исправьте все пункты. Ожидаемый результат: проект задеплоен, README оформлен, консоль чистая.
- Резюме. Составьте резюме на одну страницу по структуре из урока. Ожидаемый результат: файл PDF, который не стыдно отправить, со ссылками на GitHub и демо.
- Вопросы вслух. Ответьте вслух на 15 вопросов из урока, записывая себя. Ожидаемый результат: список тем, где вы запнулись, и повторение этих уроков.
- Лайвкодинг. Решите задачи из урока с таймером по 15 минут и ещё две новые:
flatten(плоский массив из вложенного) иdebounce. Ожидаемый результат: рабочие функции и умение объяснить их. - Пробный экзамен. Выполните пример контрольной работы целиком за 3 часа. Ожидаемый результат: работающее приложение в репозитории и подготовленная 5-минутная защита.
Итоги
- Законченный проект важнее количества: деплой, адаптивность, README, чистая консоль, никаких секретов в Git.
- Резюме — одна страница, только реальные навыки и 2–4 лучших проекта со ссылками.
- Повторите ключевые вопросы по HTML, CSS, JS, React и TypeScript и отвечайте своими словами с примерами.
- На лайвкодинге уточняйте задачу, проговаривайте решение и проверяйте граничные случаи.
- К финальному экзамену готовьтесь по чек-листу «что нужно уметь»; формат уточните у менторов.
- Поздравляем с завершением курса — дальше учитесь на реальных задачах и не бойтесь откликаться на вакансии.