TGViewer
Channel Public Channel
Frontend Alliance | Автушенко Андрей

Frontend Alliance | Автушенко Андрей

@frontendalliance

Меня зовут Автушенко Андрей. Здесь рассказываю про карьеру во frontend-разработке, менторство и личную жизнь

Менторство - frontend-alliance.ru
Отзывы - https://t.me/palaxius_reviews
Написать лично - @palaxius
YouTube: youtube.com/@FrontendAlliance
Subscribers
2.22K
Photos
101
Videos
3
Links
54
Recent Posts 11 shown
Post #142 683
Скам на рынке труда

Скам в интернете уже давно не удивляет. Но сегодняшний скам паразитирует на бедном рынке труда, которому и так плохо.
У нас уже было несколько кейсов "прохождения" в подобные компании от студентов, поэтому хочется предупредить об этом всех.

Суть схемы:
— Создается вакансия в молодую стартап компанию, конечно же она обычно как-то связано с AI (в реальности такой компании, естественно, нет).
Хорошее описание, современный стэк, удаленка, плюшки и красивые обещания.
— Размещается по всех возможных источниках: hh, чаты в телеге и прочие другие агрегаторы.
— Помимо того, что им сразу начинает писать куча потенциальных жертв, они и сами начинают активно писать кандидатам (что уже может насторожить в текущем рынке)
— Далее проводится 2 технических этапа собеседований: при этом собесы максимально всратые: созвоны могут назначить на поздний вечер и даже выходные.
— После "успешного" прохождения технички - дают тестовое. Говорят, что оплачиваемое, так что в потенциальную воронку попадает больше людей, чем могло
— И после отправки им выполненного тестового - делают оффер! На радостях ты даже забываешь, что тестовое было оплачиваемое. Но если напомнить, то предложат возместить после оформления.
— Сам оффер - это маленькая однастраничка, сделанная либо через дешевый билдер, либо с помощью нейронки.
Хотя похожие офферы мы видели и в реальные компании.
— И теперь начинается самое интересное: во время общения с ними, узнается, что оформление по ИП.
И в первую очередь эти гады нацелены именно на джунов и молодых людей, у которых с большой вероятностью ИП еще открыто не будет.
— Вы соглашаетесь с оффером - они сразу же присылают шаблон договора. Сам по себе договор сделан достаточно стандартно.
— После этого начинается этап оформления ИП — и тут начинается самое интересное: вы скидываете свои основные данные и они формируют вам персональную ссылку на открытие ИП в АльфаБанке (в наш двух кейсах был именно этот банк). В этой ссылке (или заявке) зашита рефка.
— Далее с вами связывается представитель банка, вы открываете ИП и вас кидают через уйх.

Вся схема заточена на получения реферального бабла за привод клиента в банк.
Вы при вы теряете кучу времени, и открываете ненужное ИП, за которое теперь нужно платить.

— На вопросы: можно ли оформиться по СЗ, или можно ли открыть ИП в другом банке: они отвечают, что нет. Что мол у них историческое сотрудничество с банком и что благодаря им они смогут оформить вам все по фасттрэку и в приоритете.
— Если вы скажете в процессе, что ИП у вас уже открыто или что вы собираетесь все-таки открыть ИП в другом банке — вас блокируют и все (при этом еще могут пожаловаться на аккаунт и вы еще отлетите от самой телеги)

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

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

Красные флаги таких компаний:
— это ноунейм конторы, которые не гуглятся и никто о них не знает + скорее всего что-то будет связана с AI (так как сейчас модно)
— сайт компании будет либо отсутствовать, либо (что чаще) домен будет зареган недавно (около месяца).
— аккаунты "эйчаров" и других людей, с кем вы будете коммуницировать - будут созданы недавно, фотки добавлены тоже.
— в договоре не будет никаких данных о компании, основателе, руководителе, не будет данных про ИП, ИНН, и тд (ну это же шаблон).
Так же в договоре и оффере могут быть ошибки: могут не совпадать сайты, информация про компанию и тд
— Оффер и договор - обезличены.

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

Примеры таких контор: Mise, Coperto.
Примеры аккаунтов: 1, 2, 3.

✈️ Telegram | 🎓 Менторство | 📹YouTube | 👩‍💻 Roadmap
  • 🤯 11
  • 👍 6
  • 🫡 5
  • 👀 4
  • ❤ 1
  • 👏 1
Post #141 656
  • 👍 7
  • 🔥 5
  • ❤ 3
Post #140 761

This post (sticker, poll or similar) has no web preview. Open in Telegram

  • 👍 13
  • 🔥 7
  • ✍ 4
  • ❤ 1
Post #139 864

This post (sticker, poll or similar) has no web preview. Open in Telegram

  • 🔥 18
  • 👍 8
  • ✍ 6
Post #138 953
Type refinements: все способы уточнить тип

Type Refinement (или уточнение типа) - это процесс, при котором TypeScript сужает тип значения, переходя от более общего к более конкретному, на основе проверок, условий или контекста.

Существует несколько основных способов уточнения типа.

🟣Уточнение через оператор typeof.

function printValue(value: string | number) {
if (typeof value === "string") {
console.log(value.toUpperCase()); // string
} else {
console.log(value.toFixed(2)); // number
}
}

Функция printValue принимает значение, которое может быть числом или строкой. Через проверку typeof в if блоке - мы сужаем с множества всех строк и чисел до множества строк. В ветке else, соответственно, тип автоматически станет числом.

🟣Уточнение через instanceof, когда мы работаем с классами.

class User {
constructor(public name: string) {}
}

function process(value: User | Date) {
if (value instanceof User) {
console.log(value.name);
} else {
console.log(value.toISOString());
}
}

Если значение является экземпляром определенного класса, TypeScript корректно сузит тип внутри этого условия и поймет, что в каждой ветке будет инстанс определенного класса.

🟣Проверка структуры объекта через оператор in.

type TSuccess = { ok: true; data: string };
type TError = { ok: false; error: string };

function handle(res: TSuccess | TError) {
if ("data" in res) {
console.log(res.data); // TSuccess
} else {
console.log(res.error); // TError
}
}

Здесь в примере у нас есть два типа, которые отличаются полями data и error. Проверив наличие поля data в объекте - тайпскрипт правильно определит с каким типом мы дальше будем работать.

🟣Использование дискриминирующих объединений.

type Circle = { type: "circle"; radius: number };
type Square = { type: "square"; size: number };

type Shape = Circle | Square;

function area(shape: Shape) {
switch (shape.type) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.size * shape.size;
}
}

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

🟣Также существует механизм type assertion - утверждение типа.

const el = document.getElementById("div") as HTMLDivElement;


Это не уточнение типа, а принудительное указание типа через оператор "as".
Использовать этот механизм нужно осторожно и редко, потому что он позволяет нарушить правила типизации.

При этом оператор "as" всё же проверяет пересечение типов, поэтому полностью некорректные значения передать туда не получится (скрин 1).

Конечно это можно обойти тем, что сначала привести тип к unknown, а потом уже к boolean, но как минимум это заставит разработчика задуматься, не делает ли он полную глупость.

✈️ Telegram | 🎓 Менторство | 📹YouTube | 👩‍💻 Roadmap
  • 👍 12
  • 🔥 10
  • ❤ 7
Post #136 1.58K
WeakMap и WeakSet

На защитах материала у студентов по JavaScript я регулярно вижу один и тот же пробел: когда речь заходит про встроенные структуры данных, а именно Map, Set, WeakMap и WeakSet — большинство учеников не могут полноценно объяснить, зачем нужны слабые коллекции, какие у них есть ограничения и где их можно применять.

🟣 Что это такое?

WeakMap и WeakSet это специальные коллекции в JavaScript, которые позволяют хранить данные, связанные с объектами, не мешая сборщику мусора удалять их из памяти, когда они больше не используются.

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

WeakMap хранит пары «ключ - значение» и имеет методы:
set — добавляет новую пару или перезаписывает значение ключа.
get — возвращает значение по переданному ключу, если его нет — undefined.
has — проверяет наличие ключа и возвращает true / false.
delete — удаляет пару по ключу и возвращает true, если запись была удалена, иначе false.

WeakSet хранит только значения и имеет методы:
add — добавляет новое значение и возвращает сам WeakSet.
has — проверяет наличие значения и возвращает true или false.
delete — удаляет значение и возвращает true, если оно существовало, иначе false.

🟣 Что означает Weak?

Обычные Map и Set хранят сильную ссылку на объект, поэтому пока объект находится внутри коллекции — сборщик мусора не сможет удалить его из памяти.

А в WeakMap ссылка на ключ является «слабой». Если больше нигде на этот объект нет сильных ссылок, сборщик мусора может удалить и сам объект, и соответствующую запись в WeakMap.

WeakSet работает аналогично: если объект существует только внутри WeakSet и больше нигде не используется, сборщик мусора может удалить его.

При этом очистка происходит не сразу: JavaScript сам определяет момент запуска сборщика мусора, поэтому нельзя строить логику на ожидании удаления объекта.

🟣 Какие значения можно использовать?


Ключами WeakMap и значениями WeakSet не могут быть примитивы, а только объекты.

const users = new WeakMap();

users.set('user-1', true);
// Uncaught TypeError: WeakMap key "user-1" must be an object or an unregistered symbol


«Слабые» коллекции отслеживают жизненный цикл конкретного значения в памяти. У объектов есть собственные ссылки, а примитивы работают иначе.

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

Также в актуальной спецификации есть исключение: слабые коллекции также принимают незарегистрированные Symbol'ы. Но основной сценарий их использования — работа именно с объектами.

🟣 Какие есть ограничения?


У WeakMap и WeakSet нет size, keys, values, entries и forEach. Также их нельзя перебрать через for...of.

Размер Weak-структур невозможно определить предсказуемо: он может измениться в любой момент после запуска сборщика мусора. Поэтому API, позволяющего узнать количество элементов или перебрать коллекцию, просто не существует.

Получить данные из WeakMap или проверить наличие объекта в WeakSet можно только если у вас уже есть ссылка на этот объект.

🟣 Применение WeakMap

Один из основных сценариев использования WeakMap — хранение дополнительных данных, связанных с конкретным объектом.

Например, можно хранить метаданные DOM-элемента отдельно, не добавляя служебные поля прямо в него (скрин 1). После удаления DOM-элемента - запись исчезнет автоматически, без необходимости вручную очищать коллекцию.

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

🟣 Применение WeakSet

Допустим, мы хотим проверить объект на наличие циклических ссылок (скрин 2).

Циклическая ссылка — это ситуация, когда объект прямо или косвенно ссылается сам на себя.

Если при обходе мы повторно встречаем объект, который уже находится в текущем пути обхода, значит обнаружена циклическая ссылка.

Такой подход может быть так же применим при валидации, сериализации, клонировании объектов и анализе сложных конфигураций.

✈️ Telegram | 🎓 Менторство | 📹YouTube | 👩‍💻 Roadmap
  • 🔥 19
  • 👍 6
  • ✍ 5
Post #135 1.57K
Mapped Types

Готовые утилитарные типы в TypeScript основаны на мощной возможности языка создавать новые типы на основе существующих с помощью перебора ключей и трансформации значений.

Этот механизм называется Mapped Types.

Mapped Types решают проблему повторения структуры объектов при создании вариаций типов, например, когда нужно сделать все поля обязательными, опциональными или readonly.

Мы можем создать свой Partial или Readonly.
type MyPartial<T> = {
[K in keyof T]?: T[K];
};

type MyReadonly<T> = {
readonly [K in keyof T]: T[K];
};

type User = { name: string; age: number; };

type PartialUser = MyPartial<User>;
type ReadonlyUser = MyReadonly<PartialUser>;

const partialUser: PartialUser = {};
const readonlyUser: ReadonlyUser = {};


Внутри типа используется запись K in keyof T, которая означает, что мы итерируемся по ключам переданного объекта. В K попадает сам ключ, а дальше мы возвращаем его значение.

Существуют следующие модификаторы:
? для опциональности: [K in keyof T]?: T[K]
readonly, чтобы сделать значение только для чтения: readonly [K in T]: T[K]

С помощью знака минус можно сделать обратное действие, например, убрать readonly или сделать обязательными поля, как это реализовано, например, в типе Required.
// Make all properties in T required

type Required<T> = {
[P in keyof T]-?: T[P];
};



🟣Можно использовать тип never для исключения значений, как это сделано в типах Exclude и Extract:
// Exclude from T those types that are assignable to U
type Exclude<T, U> = T extends U ? never : T;

// Extract from T those types that are assignable to U
type Extract<T, U> = T extends U ? T : never;


🟣В TypeScript 4.1 и выше можно менять имена свойств в mapped types с помощью конструкции as

type MappedTypeWithNewProperties<Type> = {
[Properties in keyof Type as NewKeyType]: Type[Properties];
};

Часть as NewKeyType говорит: «возьми старое имя свойства и преврати его в новое имя».

🟣В реальности этим не так часто приходится пользоваться в разработке.

Но на собесах по TypeScript достаточно часто просят написать свою реализацию определенного утилитарного типа.

✈️ Telegram | 🎓 Менторство | 📹YouTube | 👩‍💻 Roadmap
  • ✍ 14
  • 👍 9
  • 🔥 8
  • ❤ 1
Post #134 1.85K
Стоит ли вообще входить в IT в 2026 и как это сделать?

https://youtube.com/live/9YM4PeiYG4o

Сегодня в 14:00 буду присутствовать на стриме с Антоном и другими менторами и обсуждать актуальные вопросы IT рынка

Обсудим:
• Есть ли вакансии для новичков в 2026?
• AI всех заменит или это очередная страшилка?
• Почему не зовут на собеседования, как увеличить конверсию откликов и подняться в выдаче HH
• Как использовать AI для поиска работы и подготовки к собесам
• Какие кандидаты сейчас нужны рынку?

Я буду делиться несколькими советами про то как обучаться и как полезно использовать нейросети при обучении.

Приходите и задавайте свои вопросы в чате!)
  • 👍 16
  • 🔥 11
  • 🎉 7
  • ❤ 4
Post #133 3.42K
Курс по System Design

В конце прошлого года поучаствовал в создании курса по System Design и вот наконец он вышел!

https://youtu.be/HHQTVvMXadE
https://youtu.be/HHQTVvMXadE

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

Таймкод моей части — 3:12:10.
Но для комплексного погружения в SD - можете посмотреть весь курс, будет много полезного.

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

Заодно структурировал многие вещи и для себя — теперь эти материалы станут частью блока по System Design внутри сообщества Frontend Alliance.

В курсе:

— Какие задачи бывают на System Design
— Зачем вообще проводят этот этап у фронтенд-разработчиков
— Как проходит собеседование
— Что такое архитектура и что относится к архитектуре фронтенда
— Выбор стэка
— Стратегии режимов рендера
— Архитектурные подходы и методологии
— BFF
— UI/UX и доступность
— Оптимизация производительности
— Тестирование и метрики

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

✈️ Telegram | 🎓 Менторство | 📹 YouTube | 👩‍💻 Roadmap
  • ❤ 19
  • 🔥 11
  • 👍 7
Post #127 1.94K
Самое важное про Generics

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

Они помогают создавать переиспользуемый код для типов, избавляться от дублирования и добавлять семантическую ясность. Дженерики могут применяться к типам, интерфейсам, функциям и классам. Передаются они в угловых скобках, и их количество не ограничено. Общепринято называть первый дженерик буквой T (от слова type).
Рассмотрим на примере:

function merge(obj1: object, obj2: object) {
return {
...obj1,
...obj2,
}
}

const result = merge({ a: 1, b: 2 }, { a: 2, c: 3 })

console.log(result) // {a: 2, b: 2, c: 3}


Допустим, мы хотим затипизировать функцию merge, которая принимает два объекта и объединяет их ключи в результирующий объект. Если указать тип параметров как object, выходной тип тоже будет object, и TypeScript не сможет подсказать, какие ключи будут доступны после объединения.

Решение: использовать дженерики.
Теперь мы в угловые скобки функции будем принимать два дженерика T и K, куда попадут типы объектов, которые мы передаем в функцию на 13 строке (скрин 1).

Теперь TypeScript понимает, какой тип получится на выходе, и автокомплит подскажет все доступные поля.

Так как дженерики могут принимать любые типы, можно случайно передать, например, число, и это будет валидно в текущем коде. А мы бы не хотели этого допустить.

Чтобы ограничить возможные типы, используется ключевое слово extends.

Extends накладывает ограничения на передаваемые типы и позволяет писать более безопасный код. В нашем примере мы ограничили дженерики на передачу только объектов (скрин 2).

🟣Теперь давайте взглянем на другой пример.

function get(obj: object, key: string) {
return obj[key]
}

const result = get({ name: 'Andrey', age: 27 }, 'name')

console.log(result) // 'Andrey'


У нас есть функция get, которая принимает объект и ключ, по которому нужно получить значение. Если типизировать её напрямую, результатом будет any.

Тут нам также помогут дженерики.

Тип объекта передаем дженериком T (скрин 3).

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

В данном случае keyof извлекает все возможные значения ключей.
В нашем случае это может быть либо строка (Andrey), либо число (27).

Чтобы уточнить тип нам опять понадобится дженерик (скрин 4).

Ключ, который мы передаем вторым аргументом нужно также получать через дженерик, назовем его K. И мы обязательно должны наложить на него ограничение, что он должен быть keyof T (то есть быть одним из ключей объекта).

Теперь результирующий тип выведется во время вызова функции и правильно определится. И бонусом теперь не сможем вторым аргументом в нашу функцию передать несуществующим ключ объекта - будет ошибка.

🟣Давайте рассмотрим еще один пример, который очень часто применим во фронтенд приложениях.

Представим, что у нас есть несколько ручек бекенда, в которых структура ответа одинаковая для нескольких сущностей. Например, поля limit, pagination, size, next и есть поле items, которое является массивом этой сущности (скрин 5).

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

Написав дженерик, мы получим универсальный шаблон ответа ручек бекенда для любой сущности, нужно будет только прокинуть нужный тип (скрин 6).

Теперь у нас нет дублирование кода и легко добавлять новые сущности. Если изменится контракт бекенда - правки вносятся в одном месте, что облегчает поддержку и рефакторинг.

✈️ Telegram | 🎓 Менторство | 📹 YouTube | 👩‍💻 Roadmap
  • 🔥 16
  • 👍 8
  • ✍ 4
  • ❤ 1
Post #120 1.79K
Самое важное про Enum

В TypeScript есть enum (сокращение от enumeration: перечисление) - это специальный тип, который позволяет создавать именованные наборы значений.

Если значение не задано, элементы будут автоматически пронумерованы числами, начиная с 0.

enum Status {
Loading,
Success,
Error
}

let currentStatus: Status = Status.Success;

console.log(currentStatus); // 1, потому что Loading = 0, Success = 1 и т.д.


При этом можно задать значения явно.

enum Status {
Loading = 'loading',
Success = 'success',
Error = 'error',
}

let currentStatus: Status = Status.Success;

console.log(currentStatus); // 'success'


Enum позволяет сделать код более читаемым.
Мы избегаем «магических» строк и чисел и сразу видим, какую бизнес-ценность несёт проверка. Код при этом становится самодокументируемым.

🟣Чем enum лучше обычных объектов?
Проблема объектов в том, что мы не можем напрямую использовать объект как тип для типизации перечисления значений.
Даже используя оператор typeof мы получим тип всего объекта, а не конкретное перечисление возможных значений (скрин 1).

Enumы решает эту проблему и добавляют удобный автокомплит (скрин 2).

Но важно понимать, что enumы не пропадают бесследно.
Они компилируется в объект, который содержит все значения (скрин 3).

Именно поэтому обычные числовые enumы имеют двустороннюю связь: по значению можно получить ключ.
enum Direction {
Up, // 0
}

console.log(Direction[0]); // Output: "Up"


🟣С точки зрения оптимизации памяти - такой подход уступает обычным литералам.
Поэтому в TypeScript существуют const enum.

Вместо создания полноценного объекта при компиляции, значения подставляются напрямую как литералы, что значительно экономит память (скрин 4).

🟣Однако const enum накладывает некоторые ограничения:

- Мы теперь не можем итерироваться по enumу, так как объекта физически нет (скрин 5).

- Мы не можем использовать обратное отображение для числовых enumов, чтобы получить ключ по значению (скрин 6).

🟣Так же в современном TypeScript мы можем использовать объекты с as const как альтернативу enum.
Эта конструкция создаёт readonly объект, где все значения используются как литералы.

const Status = {
Loading: 'loading',
Success: 'success',
Error: 'error',
} as const;


Вы можете спросить: как в таком случае типизировать входные данные, если обычный объект не позволял этого сделать?

Благодаря константному объекту - теперь мы сможем затипизировать значения объекта с помощью двух операторов:
- оператор typeof — позволяет получить тип на основе объекта.
- оператор keyof — позволяет получить ключи типа.

Написав соответствующую строчку, мы можем создать тип TStatus, который будет включать только конкретные значения объекта (скрин 7).

✈️ Telegram | 🎓 Менторство | 📹 YouTube | 👩‍💻 Roadmap
  • 🔥 14
  • 👍 6
  • ✍ 4
  • ❤ 1
Older posts →

About this channel

How can I read @frontendalliance without a Telegram account?
TGViewer shows the public web preview Telegram publishes for Frontend Alliance | Автушенко Андрей: recent posts, photos, videos and the subscriber count, with no app, login or account.
How many subscribers does Frontend Alliance | Автушенко Андрей have?
Frontend Alliance | Автушенко Андрей (@frontendalliance) has 2.22K subscribers on Telegram, refreshed roughly every 30 minutes.
Does Frontend Alliance | Автушенко Андрей know I viewed it here?
No. Public channel previews carry no viewer identity, and TGViewer has no accounts or tracking of what you look up.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →