Frontend | Вопросы собесов
Сайт easyoffer.ru Реклама @easyoffer_adv ВП @easyoffer_vp Тесты t.me/+T0COHtFzCJkwMDUy Задачи t.me/+_tcX2w2EmvdmMTgy Вакансии t.me/+CgCAzIyGHHg0Nzky
Show more📈 Analytical overview of Telegram channel Frontend | Вопросы собесов
Channel Frontend | Вопросы собесов (@easy_javascript_ru) in the Russian language segment is an active participant. Currently, the community unites 18 281 subscribers, ranking 7 343 in the Technologies & Applications category and 36 918 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 18 281 subscribers.
According to the latest data from 13 June, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -122 over the last 30 days and by -9 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 9.43%. Within the first 24 hours after publication, content typically collects 5.83% reactions from the total number of subscribers.
- Post reach: On average, each post receives 1 725 views. Within the first day, a publication typically gains 1 066 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 8.
- Thematic interests: Content is focused on key topics such as ставь, браузер, html, border, flex.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“Сайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp
Тесты t.me/+T0COHtFzCJkwMDUy
Задачи t.me/+_tcX2w2EmvdmMTgy
Вакансии t.me/+CgCAzIyGHHg0Nzky”
Thanks to the high frequency of updates (latest data received on 14 June, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
class Service {
constructor(repository) {
this.repository = repository;
}
}
🟠Производительность (затраты на создание объектов)
Если DI используется через контейнеры, они могут замедлять выполнение программы, так как:
Создание объектов может занимать больше времени (особенно при ленивой инициализации).
Поиск зависимостей в контейнере тоже требует времени.
В Angular, NestJS и других фреймворках DI может потреблять больше ресурсов, чем обычное создание объектов.
🟠Скрытая сложность и магия
Когда зависимости внедряются автоматически через контейнер, код становится менее очевидным.
@Injectable()
class Service {
constructor(private readonly repository: Repository) {}
}
🟠Проблемы с тестированием
Хотя DI часто называют удобным для тестирования, на практике могут возникнуть сложности:
Если контейнер создаёт объекты динамически, тесты могут работать нестабильно.
Нужно явно мокать зависимости, что может усложнять настройку тестов.
class Service {
constructor(repository) {
this.repository = repository;
}
}
const service = new Service(new Repository()); // Проблема при тестировании – жестко задана зависимость
Здесь тестировать Service сложно, потому что Repository создаётся вручную. Приходится использовать мок-объекты
const mockRepository = { getData: () => "mock data" };
const service = new Service(mockRepository);
🟠DI не всегда нужен
В маленьких проектах использование DI может быть излишним. Простое создание объектов может быть проще и понятнее, чем настройка DI-контейнера.
const repository = new Repository();
const service = new Service(repository);
Ставь 👍 и забирай 📚 Базу знанийstate) или свойства (props) изменяются. Однако часто это приводит к ненужным рендерам, которые можно избежать.
🚩Почему важна оптимизация рендеринга?
🟠Производительность
Чем больше компонентов рендерится без необходимости, тем больше времени тратится на вычисления и обновления DOM.
🟠Экономия ресурсов
Избегая лишних рендеров, приложение работает быстрее, а пользовательский интерфейс становится более отзывчивым.
🟠Лучший UX
Плавная работа интерфейса критична для сложных приложений с большим количеством данных.
🚩Основные подходы к оптимизации рендеринга
🟠Мемоизация компонентов
React предоставляет утилиту React.memo, чтобы предотвращать ререндеринг компонента, если его props не изменились.
import React from 'react';
const MyComponent = React.memo(({ count }) => {
console.log('Рендер компонента');
return <div>Счётчик: {count}</div>;
});
// Использование
export default function App() {
const [count, setCount] = React.useState(0);
return (
<div>
<MyComponent count={count} />
<button onClick={() => setCount(count + 1)}>Увеличить</button>
</div>
);
}
🟠Использование `useMemo` и `useCallback`
Эти хуки используются для предотвращения повторных вычислений и создания функций при каждом рендере.
import React, { useMemo } from 'react';
function ExpensiveCalculationComponent({ number }) {
const calculatedValue = useMemo(() => {
console.log('Выполняются сложные вычисления...');
return number ** 2;
}, [number]); // Пересчитывается только если `number` изменился
return <div>Результат: {calculatedValue}</div>;
}
Пример useCallback
import React, { useCallback, useState } from 'react';
const Child = React.memo(({ onClick }) => {
console.log('Рендер дочернего компонента');
return <button onClick={onClick}>Кликни меня</button>;
});
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Кнопка нажата');
}, []); // Создаётся одна и та же функция между рендерами
return (
<div>
<Child onClick={handleClick} />
<button onClick={() => setCount(count + 1)}>Увеличить {count}</button>
</div>
);
}
🟠Разделение кода и ленивый рендеринг
Использование React.lazy и Suspense позволяет загружать компоненты только тогда, когда они необходимы.
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<div>Загрузка...</div>}>
<LazyComponent />
</Suspense>
);
}
🟠Проверка зависимости в `useEffect`
Избегайте запуска побочных эффектов, если зависимости не изменились.
React.useEffect(() => {
console.log('Эффект сработал!');
}, [/* следите только за нужными зависимостями */]);
🟠Избегайте анонимных функций и объектов в `props`
Передача новых объектов и функций через props вызывает лишние рендеры.
<ChildComponent data={{ key: 'value' }} />
Лучше так
const data = { key: 'value' };
<ChildComponent data={data} />;
🟠Разделение больших компонентов
Если компонент слишком сложный, разделите его на более мелкие, чтобы React мог эффективно управлять состоянием и перерисовкой.
🟠Использование ключей при рендере списков
Каждый элемент списка должен иметь уникальный ключ, чтобы React мог правильно отслеживать изменения.
{items.map(item => (
<div key={item.id}>{item.name}</div>
))}
Ставь 👍 и забирай 📚 Базу знанийvar. Однако у него были проблемы, такие как отсутствие блочной области видимости и возможность повторного объявления. С введением let и const эти проблемы решены.
let — для переменных, которые могут изменяться.
const — для переменных, которые нельзя переназначить (но можно изменять содержимое, если это объект или массив).
let a = 10;
a = 20; // Работает
const b = 30;
// b = 40; // Ошибка: Нельзя переназначить
🟠Стрелочные функции (Arrow Functions)
Стрелочные функции дают более лаконичный синтаксис для объявления функций. Они также не создают собственный this, а используют this из окружающего контекста.
// Обычная функция
function add(a, b) {
return a + b;
}
// Стрелочная функция
const add = (a, b) => a + b;
console.log(add(2, 3)); // 5
🟠Шаблонные строки (Template Literals)
Раньше строки приходилось склеивать с помощью конкатенации (+). Шаблонные строки (обозначаются обратными кавычками ``) позволяют вставлять переменные и выражения прямо в текст.
const name = "Alice";
const message = `Привет, ${name}! Добро пожаловать.`;
console.log(message); // Привет, Alice! Добро пожаловать.
🟠Деструктуризация (Destructuring)
Деструктуризация позволяет извлекать значения из массивов или объектов и присваивать их переменным.
// Деструктуризация массива
const arr = [1, 2, 3];
const [first, second] = arr;
console.log(first, second); // 1, 2
// Деструктуризация объекта
const user = { name: "Alice", age: 25 };
const { name, age } = user;
console.log(name, age); // Alice 25
🟠Модули (Modules)
ES6 добавил встроенную поддержку модулей через import и export. Теперь код можно организовывать и повторно использовать более эффективно.
// В модуле user.js
export const greet = (name) => `Привет, ${name}`;
// В другом файле
import { greet } from './user.js';
console.log(greet("Alice")); // Привет, Alice
🟠Операторы "..." (Spread и Rest)
Оператор ... используется для работы с массивами, объектами и функциями.
Spread — для разворачивания массивов и объектов.
Rest — для сбора оставшихся элементов в массив или объект.
// Spread
const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4];
console.log(arr2); // [1, 2, 3, 4]
// Rest
const [first, ...rest] = [1, 2, 3, 4];
console.log(first); // 1
console.log(rest); // [2, 3, 4]
🟠Классы (Classes)
Классы добавляют объектно-ориентированный стиль программирования. Это синтаксический сахар над прототипами.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} говорит.`);
}
}
const dog = new Animal("Собака");
dog.speak(); // Собака говорит.
🟠Обещания (Promises)
Обещания (Promises) упрощают работу с асинхронным кодом, заменяя вложенные колбэки (callback hell).
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Данные получены"), 1000);
});
};
fetchData().then((data) => console.log(data)); // Данные получены
🟠Итераторы и генераторы
Итераторы дают возможность обходить коллекции (например, массивы) шаг за шагом.
Генераторы — функции, которые можно приостанавливать и возобновлять.
function* numbers() {
yield 1;
yield 2;
yield 3;
}
const gen = numbers();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
Ставь 👍 и забирай 📚 Базу знаний:hover — применяется к элементу, когда на него наводят курсор мыши.
a:hover {
color: red; /* Ссылка станет красной при наведении /
}
:focus — применяется к элементу, когда он получает фокус (например, при переходе на элемент с помощью клавиатуры или при клике мыши).
input:focus {
border-color: blue; / Граница инпута станет синей при фокусе /
}
:active — применяется к элементу в момент его активации пользователем (например, во время клика по кнопке).
button:active {
transform: scale(0.98); / Кнопка немного уменьшится при клике /
}
:nth-child() — позволяет стилизовать элементы в зависимости от их порядка среди детей родительского элемента.
li:nth-child(odd) {
background-color: gray; / Заливка каждого нечетного элемента списка /
}
:not() — исключает из выборки элементы, соответствующие указанному селектору.
div:not(.special) {
color: green; / Применяется к каждому div, который не имеет класса special */
}
🚩Зачем нужны псевдоклассы?
Они делают CSS более мощным и гибким, позволяя разработчикам применять стили к элементам на основе их состояния или положения в документе, без изменения HTML-структуры. Это особенно полезно для создания интерактивных и реактивных пользовательских интерфейсов, где визуальное состояние элемента должно меняться в ответ на действия пользователя.
Ставь 👍 и забирай 📚 Базу знанийdist появляются статические файлы (index.html, app.js, styles.css).
server {
listen 80;
server_name myapp.com;
root /var/www/myapp/dist;
index index.html;
location / {
try_files $uri /index.html;
}
}
🟠Как Nginx проксирует запросы к бэкенду?
Если фронтенд (myapp.com) и бэкенд (api.myapp.com) находятся на разных серверах, Nginx может перенаправлять запросы на API.
server {
listen 80;
server_name myapp.com;
root /var/www/myapp/dist;
index index.html;
location / {
try_files $uri /index.html;
}
# Проксирование API-запросов
location /api/ {
proxy_pass http://localhost:5000/; # Node.js, Python, PHP и т. д.
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
🟠Как Nginx балансирует нагрузку?
Если у нас несколько бэкенд-серверов, Nginx может распределять нагрузку между ними.
upstream backend {
server backend1.myapp.com;
server backend2.myapp.com;
}
server {
listen 80;
server_name api.myapp.com;
location / {
proxy_pass http://backend;
}
}
🟠Как Nginx ускоряет сайт с кэшем?
Кэширование уменьшает нагрузку на сервер и ускоряет загрузку страниц.
location /static/ {
expires 7d; # Кэшировать файлы на 7 дней
add_header Cache-Control "public, max-age=604800";
}
Ставь 👍 и забирай 📚 Базу знаний
Available now! Telegram Research 2025 — the year's key insights 
