Frontend | Вопросы собесов
19.4K subscribers
30 photos
1 video
770 links
Сайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp

Тесты t.me/+T0COHtFzCJkwMDUy
Задачи t.me/+_tcX2w2EmvdmMTgy
Вакансии t.me/+CgCAzIyGHHg0Nzky
Download Telegram
🤔 Какие используешь подходы для написания приложения которую проще поддерживать, чем делать первоначальную разработку?

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

🟠Разделение ответственности (Separation of Concerns)
Это значит, что код должен быть разделен по зонам ответственности. В frontend-разработке это проявляется в:
Чистом разделении логики, представления и данных (например, с помощью архитектуры MVC, MVVM или FLUX).
Использовании компонентов в React/Vue или шаблонов в Angular.
Разделении CSS, JS и HTML, либо использовании методологий, где стили хранятся рядом с компонентом (CSS Modules, Styled Components).
Вместо того, чтобы писать всю логику и разметку в одном файле:
function App() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}



Я разделяю бизнес-логику и представление
// CounterLogic.js
export function useCounter() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
return { count, increment };
}

// Counter.js
import { useCounter } from "./CounterLogic";
function Counter() {
const { count, increment } = useCounter();
return <button onClick={increment}>Count: {count}</button>;
}



🟠Компонентный подход и повторное использование кода
Frontend-приложения должны строиться из переиспользуемых и изолированных компонентов. Это уменьшает дублирование кода и делает его понятным.
// Button.js (переиспользуемый компонент)
function Button({ onClick, children }) {
return <button onClick={onClick}>{children}</button>;
}

// Counter.js (использует Button)
function Counter() {
const [count, setCount] = useState(0);
return <Button onClick={() => setCount(count + 1)}>Count: {count}</Button>;
}



🟠Чистый код и читаемость
Код должен быть понятным не только мне, но и другим разработчикам.
Понятные имена переменных и функций. Вместо xuserAge, вместо doSmth()calculateTotalPrice().
Меньше вложенности. Вместо кучи if и else, лучше использовать early return.
Разбиение кода на модули. Один файл = одна зона ответственности.
function getDiscountedPrice(price, discount) {
if (discount <= 0) return price;
return price - price * (discount / 100);
}



🟠Состояние приложения: локальное vs глобальное
В зависимости от сложности приложения нужно правильно управлять состоянием:
Локальное состояние – useState (React), ref (Vue) для простых данных внутри компонента.
Глобальное состояние – Redux, MobX, Zustand, Pinia, Context API – когда данные нужны многим компонентам.
Серверное состояние – React Query, SWR – когда данные приходят с API и их нужно кешировать.

🟠Следование принципам SOLID и DRY
DRY (Don't Repeat Yourself) – не повторяем код, используем функции, хуки, компоненты.
SOLID – например, принцип единственной ответственности (Single Responsibility Principle) гласит, что каждый компонент или функция должны решать только одну задачу.
function sendEmailAndSaveToDB(user) {
sendEmail(user.email);
saveUserToDatabase(user);
}


Лучше разделить логику
function sendEmail(email) { /* отправка письма */ }
function saveUserToDatabase(user) { /* сохранение в БД */ }
function registerUser(user) {
sendEmail(user.email);
saveUserToDatabase(user);
}


🟠Использование TypeScript
TypeScript помогает избежать ошибок и делать код предсказуемым.
type User = {
id: number;
name: string;
};

function getUserName(user: User): string {
return user.name;
}



🟠Документация и кодстайл
ESLint + Prettier → автоформатирование и проверка стиля.
JSDoc/TypeScript → документация функций и типов данных.
Storybook → для документирования UI-компонентов.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что известно о StackBlitz?

StackBlitz — онлайн-редактор кода, особенно хорош для проектов на Angular, React, TypeScript и WebAssembly.
Особенности:
- Поддерживает instant preview.
- Работает без сервера — использует WebContainers.
- Отлично подходит для демонстраций, обучения и изоляции тестов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое usecontext?

Это один из встроенных хуков, который позволяет компонентам подписываться на контекст и получать доступ к данным контекста. Используется для передачи данных через дерево компонентов без необходимости передавать пропсы на каждом уровне. Это особенно полезно для глобальных данных, таких как текущий авторизованный пользователь, тема (светлая/темная) или настройки локализации.

🚩Как он работает

🟠Создание контекста
Для создания контекста используется функция createContext. Она возвращает объект контекста, который содержит два компонента: Provider и Consumer.
      import React, { createContext, useState } from 'react';

const MyContext = createContext();


🟠Provider
Компонент Provider используется для предоставления значения контекста всем дочерним компонентам. Все компоненты внутри Provider могут получить доступ к значениям, переданным в value.
      const MyProvider = ({ children }) => {
const [state, setState] = useState('Hello World');

return (
<MyContext.Provider value={{ state, setState }}>
{children}
</MyContext.Provider>
);
};


🟠useContext
Используется для подписки на контекст в функциональных компонентах. Он принимает объект контекста, возвращаемый из createContext, и возвращает текущее значение контекста.
      import React, { useContext } from 'react';

const MyComponent = () => {
const { state, setState } = useContext(MyContext);

return (
<div>
<p>{state}</p>
<button onClick={() => setState('New Value')}>Change Value</button>
</div>
);
};


Полный пример
import React, { createContext, useState, useContext } from 'react';

// Создание контекста
const MyContext = createContext();

const MyProvider = ({ children }) => {
const [state, setState] = useState('Hello World');

return (
<MyContext.Provider value={{ state, setState }}>
{children}
</MyContext.Provider>
);
};

const MyComponent = () => {
const { state, setState } = useContext(MyContext);

return (
<div>
<p>{state}</p>
<button onClick={() => setState('New Value')}>Change Value</button>
</div>
);
};

const App = () => (
<MyProvider>
<MyComponent />
</MyProvider>
);

export default App;


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое React?

React — это библиотека JavaScript для создания пользовательских интерфейсов, основанная на компонентах и виртуальном DOM, что делает её эффективной и удобной для масштабирования.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое шаблонные литералы, и для чего они нужны?

Были введены в ECMAScript 2015 (ES6) и представляют собой улучшение стандартных строк в JavaScript. Они облегчают работу с строками, предоставляя более удобный синтаксис для создания многострочных строк, интерполяции переменных и встроенных выражений.

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

🟠Интерполяция переменных и выражений
Шаблонные литералы позволяют встраивать переменные и выражения внутрь строк с помощью синтаксиса ${}.
const name = 'Alice';
const age = 25;

const greeting = `Hello, my name is ${name} and I am ${age} years old.`;

console.log(greeting);
// Вывод: Hello, my name is Alice and I am 25 years old.


🟠Многострочные строки
Шаблонные литералы позволяют создавать многострочные строки без необходимости использования символов переноса строки (\n).
const multiLineString = `This is a string
that spans across
multiple lines.`;

console.log(multiLineString);
// Вывод:
// This is a string
// that spans across
// multiple lines.


🟠Встроенные выражения
Внутри шаблонных литералов можно использовать любые JavaScript-выражения.
const a = 5;
const b = 10;

const result = `The sum of ${a} and ${b} is ${a + b}.`;

console.log(result);
// Вывод: The sum of 5 and 10 is 15.


🟠Вызов функций внутри шаблонных литералов
Можно вызывать функции и методы внутри шаблонных литералов.
function toUpperCase(str) {
return str.toUpperCase();
}

const name = 'Alice';

const loudGreeting = `Hello, ${toUpperCase(name)}!`;

console.log(loudGreeting);
// Вывод: Hello, ALICE!


🟠Тегированные шаблонные литералы
Тегированные шаблонные литералы позволяют обработать строку с помощью функции перед ее окончательной интерпретацией.
function tag(strings, ...values) {
console.log(strings);
console.log(values);
return 'Tagged template';
}

const name = 'Alice';
const age = 25;

const taggedResult = tag`Name: ${name}, Age: ${age}`;

console.log(taggedResult);
// Вывод:
// [ 'Name: ', ', Age: ', '' ]
// [ 'Alice', 25 ]
// Tagged template


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 В каком методе жизненного цикла необходимо делать очистку?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Когда брать абсолютные величины а когда относительные?

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

🚩Абсолютные величины (например, px, pt, cm, in)

Имеют фиксированные размеры и не зависят от других элементов или размеров экрана. Они всегда остаются одинаковыми, независимо от контекста.

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

1⃣Пиксели (`px`)
Точные размеры: Когда вам нужно задать точные размеры элементов, например, для пиксельной точности в дизайне.
Фиксированные элементы: Для элементов, размеры которых не должны изменяться в зависимости от экрана или родительского элемента (например, логотипы или иконки).
Маленькие декоративные элементы: Когда размеры элементов настолько малы, что относительные единицы могут привести к неконтролируемому результату.
.logo {
width: 100px;
height: 50px;
}


🚩Относительные величины (например, %, em, rem, vw, vh)

Изменяются в зависимости от других элементов или размеров экрана. Они позволяют создавать более гибкие и адаптивные макеты.

🟠Проценты (`%`)
Адаптивные макеты: Когда нужно, чтобы элемент занимал определенный процент от размера родительского элемента.
Контейнеры и блоки: Для ширины и высоты блоков, которые должны изменяться вместе с размерами родителя.
.container {
width: 80%;
height: 50%;
}


🟠Эм (`em`)
Шрифты: Когда нужно задавать размер шрифта относительно размера шрифта родителя.
Внутренние отступы и поля: Для создания элементов, которые масштабируются вместе с текстом.
.text {
font-size: 1.2em;
margin: 1em;
}


🟠Рем (`rem`):
Глобальная консистентность: Когда нужно задавать размер относительно корневого элемента (обычно <html>), что обеспечивает более предсказуемое масштабирование.
Шрифты и отступы: Для элементов, которые должны быть пропорциональны базовому размеру шрифта
body {
font-size: 16px;
}

.header {
font-size: 2rem; /* 32px */
margin: 1rem; /* 16px */
}


🟠Вьюпорт (`vw`, `vh`):
Адаптивные размеры: Когда размеры элементов должны быть пропорциональны размеру вьюпорта (окна браузера).
Фоновые изображения и видео: Для элементов, которые должны занимать определенный процент от экрана.
.hero {
width: 100vw;
height: 100vh;
}


🚩Комбинированное использование

Иногда можно комбинировать абсолютные и относительные единицы для достижения наилучшего результата.
.container {
width: 80%; /* Относительная ширина */
padding: 20px; /* Абсолютный внутренний отступ */
}

.text {
font-size: 1.5rem; /* Относительный размер шрифта */
margin: 2em; /* Относительный внешний отступ */
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как использовать useEffect?

useEffect — это хук в React, который позволяет выполнять побочные эффекты в функциональных компонентах, таких как запросы к API или подписки. Он принимает функцию, которая выполняется после рендеринга, и массив зависимостей, определяющий, когда эффект должен обновляться. Если массив зависимостей пуст, эффект выполнится только один раз при монтировании компонента.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Чем отличается замыкание от области видимости?

Замыкание и область видимости — это два фундаментальных концепта в JavaScript, связанных с работой переменных, но они решают разные задачи. Давайте разберёмся в их отличиях.

🚩Область видимости (Scope)

Область видимости определяет, где в коде можно обращаться к переменной. В JavaScript есть три основные области видимости:
Глобальная область видимости – переменные доступны в любом месте кода.
Область видимости функции (функциональная) – переменные доступны только внутри функции, где они были объявлены.
Блочная область видимости (с let и const) – переменные доступны только внутри блока {}.
function testScope() {
let x = 10; // x доступна только внутри testScope
console.log(x); // 10
}
console.log(x); // Ошибка: x не определена



🚩Замыкание (Closure)

Замыкание – это функция, которая запоминает область видимости, в которой была создана, даже после выхода из неё. То есть, если внутренняя функция использует переменные внешней функции, она "захватывает" их и может использовать даже после завершения работы внешней функции.
function outer() {
let count = 0;

return function inner() {
count++;
console.log(count);
};
}

const counter = outer(); // outer выполняется, но переменная count остается в памяти
counter(); // 1
counter(); // 2
counter(); // 3


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что делают выражения в JS?

Они возвращают значение:
- 1 + 2
- a === b
- function(){}


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Когда стоит использовать тип any?

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

🚩Если тип данных неизвестен заранее (например, ответ от API)
Иногда сервер может вернуть разные структуры данных, и невозможно заранее определить точный тип.
async function fetchData(url: string): Promise<any> {
const response = await fetch(url);
return response.json();
}


Лучший вариант — использовать интерфейсы вместо any:
interface User {
id: number;
name: string;
}

async function fetchUser(url: string): Promise<User> {
const response = await fetch(url);
return response.json() as User;
}


🚩При миграции JavaScript в TypeScript

Если проект на чистом JavaScript, добавление TypeScript может сломать код. any помогает постепенно вводить строгую типизацию.
function log(value: any) {
console.log(value);
}


🚩Когда работаем с динамическими структурами (например, `localStorage`)

В localStorage можно сохранить что угодно, поэтому при чтении данных тип неизвестен.
const data: any = localStorage.getItem("user");


Лучше сразу привести any к нужному типу
const user = JSON.parse(localStorage.getItem("user") || "{}") as { id: number; name: string };


🚩Когда пишем универсальную библиотеку

Если функция должна работать с разными типами, any может быть временным решением.
function mergeObjects(obj1: any, obj2: any): any {
return { ...obj1, ...obj2 };
}


Лучший вариант с generic (T вместо any)
function mergeObjects<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как работать с асинхронным JS?

Используются:
- колбэки — старый способ;
- промисы — современная модель с .then()/.catch();
- async/await — синтаксический сахар над промисами, читаемость как у синхронного кода.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Как проверить правильную иерархию html заголовков?

Проверить правильную иерархию HTML-заголовков важно для улучшения доступности (Accessibility) и SEO. Правильная структура заголовков помогает пользователям (включая тех, кто использует скринридеры) и поисковым системам лучше понимать содержание страницы.

🚩Зачем нужна правильная иерархия заголовков?

🟠Логическая структура
Заголовки задают структуру страницы, разбивая контент на разделы и подразделы. Это как оглавление книги.
🟠Доступность
Люди, использующие вспомогательные технологии (например, скринридеры), полагаются на правильные заголовки для навигации по странице.
🟠SEO
Поисковые системы оценивают структуру заголовков для индексации и понимания ключевых тем страницы.

🚩Что значит "правильная иерархия заголовков"?

🟠`<h1>`
Заголовок страницы (должен быть уникальным и только один на странице).
🟠`<h2>`
Подразделы <h1>.
🟠`<h3>`
Подразделы <h2>, и так далее.

<h1>Главный заголовок страницы</h1>
<h2>Раздел 1</h2>
<h3>Подраздел 1.1</h3>
<h3>Подраздел 1.2</h3>
<h2>Раздел 2</h2>
<h3>Подраздел 2.1</h3>
<h4>Подраздел 2.1.1</h4>


🚩Как проверить иерархию заголовков?

🟠Ручная проверка HTML-кода
Вручную просмотрите HTML-код страницы и убедитесь, что заголовки идут в порядке. Например, <h1><h2><h3> и так далее, без "перескакивания". Избегайте "пропуска уровней" (например, от <h2> сразу к <h4>).

🟠Использование браузерных DevTools
В браузере откройте DevTools (например, в Chrome нажмите F12 или Ctrl+Shift+I). Перейдите на вкладку "Elements" (Элементы). Найдите заголовки (<h1>, <h2> и так далее) и проверьте их последовательность.

🟠Инструменты для проверки доступности
Используйте расширения или инструменты для оценки доступности, такие как: Lighthouse (встроено в Chrome DevTools). Выполните аудит доступности и посмотрите рекомендации. WAVE (Web Accessibility Evaluation Tool) — онлайн-инструмент для анализа доступности. Эти инструменты покажут ошибки или пропуски в структуре заголовков.

🟠Скрипт для автоматической проверки
Если вы работаете над большим проектом, можно написать скрипт для проверки иерархии заголовков.
const headings = [...document.querySelectorAll('h1, h2, h3, h4, h5, h6')];
headings.forEach((heading, index) => {
console.log(`${index + 1}: ${heading.tagName} - ${heading.textContent.trim()}`);
});


🟠Плагин для анализа заголовков
Для популярных CMS (например, WordPress) существуют плагины, которые проверяют структуру заголовков, например, Yoast SEO.

🚩Примеры ошибок в структуре и как их исправить

Ошибка: Пропуск уровней заголовков
<h1>Главный заголовок</h1>
<h3>Подраздел</h3> <!-- Пропущен <h2> -->


Исправление
<h1>Главный заголовок</h1>
<h2>Подраздел</h2>


Ошибка: Несколько <h1> на одной странице
<h1>Главный заголовок</h1>
<h1>Еще один заголовок</h1>


Исправление
<h1>Главный заголовок</h1>
<h2>Еще один заголовок</h2>


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Для чего нужен flex?

Flexbox (Flexible Box Layout) — система расположения элементов в контейнере:
- выравнивание по оси;
- растягивание/сжатие;
- распределение пространства;
- управление направлением.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Можно ли перезапустить остановленный promise?

Нет, Promise в JavaScript нельзя перезапустить. Промисы являются одноразовыми: после того как они переходят в одно из состояний — выполнен (resolved) или отклонён (rejected) — их состояние больше не может измениться. Это одно из ключевых свойств промисов.

🚩Почему нельзя перезапустить Promise?

Промис, как только выполняется, становится иммутабельным. После выполнения (resolve) или отклонения (reject), он остаётся в этом состоянии навсегда.
Промисы предназначены для представления единственного результата асинхронной операции. Их дизайн не предполагает повторного запуска той же самой асинхронной логики.

const myPromise = new Promise((resolve, reject) => {
resolve('Done!');
});

myPromise.then((result) => console.log(result)); // "Done!"

// Даже если вы попытаетесь вызвать resolve или reject снова, ничего не произойдет
myPromise.then((result) => console.log(result)); // "Done!" (результат уже закеширован)


🚩Что делать, если нужно "перезапустить" асинхронную операцию?

Если вы хотите выполнить операцию заново, вместо "перезапуска" Promise нужно создать новый Promise или использовать функцию, которая возвращает новый Promise каждый раз.
function createPromise() {
return new Promise((resolve, reject) => {
setTimeout(() => resolve('Я новый промис!'), 1000);
});
}

// Первый вызов
createPromise().then((result) => console.log(result)); // "Я новый промис!"

// "Перезапуск"
createPromise().then((result) => console.log(result)); // "Я новый промис!" (новый промис создан)


🚩Как это сделать с использованием `async/await`?

Это синтаксический сахар над промисами. Если вам нужно "перезапустить" асинхронную операцию, просто вызовите асинхронную функцию ещё раз.
async function fetchData() {
return new Promise((resolve) => {
setTimeout(() => resolve('Данные загружены!'), 1000);
});
}

async function main() {
const data1 = await fetchData();
console.log(data1); // "Данные загружены!"

const data2 = await fetchData(); // "Перезапуск" fetchData
console.log(data2); // "Данные загружены!"
}

main();


🚩Повторная попытка выполнения промиса (ретрай)

Если вам нужно повторно попытаться выполнить операцию (например, в случае неудачи), можно реализовать "ретрай". Это особенно полезно для операций вроде сетевых запросов.
function fetchDataWithRetry(retries) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.7) { // 70% шансов на ошибку
resolve('Данные успешно загружены!');
} else {
reject('Ошибка загрузки данных');
}
}, 1000);
}).catch((error) => {
if (retries > 0) {
console.log(`Повторная попытка... Осталось: ${retries}`);
return fetchDataWithRetry(retries - 1); // Рекурсивный вызов
} else {
throw error; // Если попытки исчерпаны, выбрасываем ошибку
}
});
}

fetchDataWithRetry(3)
.then((data) => console.log(data))
.catch((error) => console.error(error));


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Для чего нужен rebase?

rebase в Git применяется для:
- переписывания истории коммитов, чтобы сделать её «чище».
- Переноса текущих коммитов на новую базу, например, на обновлённую ветку main.
- Помогает избежать лишних merge-коммитов и поддерживать линейную историю.
Он особенно полезен, если ты хочешь «подстроиться» под чужие изменения до merge.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Зачем нужен nginx?

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

🟠Как Nginx раздаёт фронтенд-приложение?
Когда мы билдим SPA-приложение (например, React/Vue/Angular), в папке 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";
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое поток?

Поток (flow) — это естественный порядок расположения элементов на странице: сверху вниз, слева направо. Влияет на поведение и позиционирование элементов в HTML-документе.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое псевдоклассы?

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

: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-структуры. Это особенно полезно для создания интерактивных и реактивных пользовательских интерфейсов, где визуальное состояние элемента должно меняться в ответ на действия пользователя.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое относительная ссылка?

Относительная ссылка указывает путь относительно текущего документа или директории. Удобна для работы внутри сайта или проекта.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM