Frontend | Вопросы собесов
19.1K subscribers
35 photos
1 video
988 links
Download Telegram
🤔 Что такое и чем опасен XSS?

XSS (Cross-Site Scripting) — это атака, при которой злоумышленник внедряет вредоносный JavaScript-код в страницу. Опасен тем, что может украсть cookies, данные с формы, сделать редирект или отправить вредоносный запрос от имени пользователя.

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

В JavaScript можно замерить скорость выполнения кода с помощью Date.now(), но есть более точные способы. Давайте разберём разные варианты.

🚩Использование `Date.now()`

Метод Date.now() возвращает количество миллисекунд с 1 января 1970 года (Unix-время). Можно запомнить время до и после выполнения кода, а затем вычислить разницу.
const start = Date.now(); // Фиксируем время начала

// Код, время выполнения которого нужно измерить
for (let i = 0; i < 1e6; i++) { Math.sqrt(i); }

const end = Date.now(); // Фиксируем время окончания
console.log(`Время выполнения: ${end - start} мс`);


🚩Использование `performance.now()` (Более точный способ)

Метод performance.now() возвращает время с микросекундной точностью (до тысячных долей миллисекунды). Он точнее, чем Date.now(), так как измеряет время с высокой детализацией.
const start = performance.now();

for (let i = 0; i < 1e6; i++) { Math.sqrt(i); }

const end = performance.now();
console.log(`Время выполнения: ${(end - start).toFixed(3)} мс`);


🚩Использование `console.time()`

Если нужно просто измерить время выполнения блока кода, можно воспользоваться console.time() и console.timeEnd().
console.time("Мой код");

for (let i = 0; i < 1e6; i++) { Math.sqrt(i); }

console.timeEnd("Мой код"); // Выведет время выполнения


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9💊1
🤔 Какие бывают CSS units (единицы измерения)?

- Абсолютные: px, pt, cm, mm, in;
- Относительные: em, rem, %, vw, vh, vmin, vmax;
- Функциональные: calc(), clamp() и др.
Относительные единицы зависят от размера родителя, корня или окна браузера.


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

Redux – мощный инструмент, но не всегда он необходим. Существует множество альтернатив, каждая из которых подходит для разных сценариев.

🚩React Context API + useReducer

Подходит для небольших и средних приложений
Встроено в React (не требует установки дополнительных библиотек)
useContext` позволяет передавать данные по дереву компонентов без "прокидывания" через props
useReducer работает как Redux, но проще
const AuthContext = createContext();

function authReducer(state, action) {
switch (action.type) {
case "LOGIN":
return { ...state, isAuthenticated: true, user: action.payload };
case "LOGOUT":
return { ...state, isAuthenticated: false, user: null };
default:
return state;
}
}

function AuthProvider({ children }) {
const [state, dispatch] = useReducer(authReducer, {
isAuthenticated: false,
user: null,
});

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

function LoginButton() {
const { dispatch } = useContext(AuthContext);
return (
<button onClick={() => dispatch({ type: "LOGIN", payload: "Иван" })}>
Войти
</button>
);
}


🚩Zustand

Проще Redux, но с теми же возможностями
Нет лишних actions и reducers, только функции
import { create } from "zustand";

const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));

function Counter() {
const { count, increment } = useStore();
return <button onClick={increment}>Счетчик: {count}</button>;
}


🚩Recoil

Идеален для React-приложений
Гибче, чем Redux, с концепцией "атомов" (раздельные состояния)
import { atom, useRecoilState } from "recoil";

const countState = atom({
key: "count",
default: 0,
});

function Counter() {
const [count, setCount] = useRecoilState(countState);
return <button onClick={() => setCount(count + 1)}>Счетчик: {count}</button>;
}


🚩Jotai

Напоминает Recoil, но без сложных концепций
Поддерживает React Suspense и асинхронные состояния
import { atom, useAtom } from "jotai";

const countAtom = atom(0);

function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount(count + 1)}>Счетчик: {count}</button>;
}


🚩MobX

Автоматически отслеживает изменения состояния
Удобен для сложных приложений
import { makeAutoObservable } from "mobx";
import { observer } from "mobx-react-lite";

class CounterStore {
count = 0;

constructor() {
makeAutoObservable(this);
}

increment() {
this.count++;
}
}

const store = new CounterStore();

const Counter = observer(() => (
<button onClick={() => store.increment()}>Счетчик: {store.count}</button>
));


🚩XState

Подходит для сложных логик (например, UI-анимаций, состояний формы)
Удобно описывать последовательности действий
import { createMachine, interpret } from "xstate";

const toggleMachine = createMachine({
id: "toggle",
initial: "inactive",
states: {
inactive: { on: { TOGGLE: "active" } },
active: { on: { TOGGLE: "inactive" } },
},
});

const service = interpret(toggleMachine).start();
service.send("TOGGLE"); // Меняет состояние


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

- Через REST API с методами POST, GET, PUT, DELETE;
- На уровне базы — с SQL-операциями: INSERT, SELECT, UPDATE, DELETE;
- На UI — с формами создания, таблицами, редактированием и удалением записей.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6💊4👍2
🤔 Что делает и для чего нужна функци function.Prototype.Bind?

bind() – это метод, который создает новую функцию с привязанным контекстом (this) и (опционально) фиксированными аргументами.

🚩Основные возможности `bind()`

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

Пример: потеря this без bind()
const user = {
name: "Иван",
sayHello() {
console.log(`Привет, ${this.name}!`);
},
};

setTimeout(user.sayHello, 1000); // this = undefined


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊6🤔3
🤔 Как работает hot reload (на примере Vue CLI)?

1. Webpack/Vite следит за файлами.
2. При изменении модуля:
- обновляется только этот модуль в браузере.
- состояние приложения сохраняется.
3. Vue CLI использует Webpack HMR API, чтобы перерендерить компоненты без перезагрузки страницы.
Это ускоряет разработку и упрощает отладку.


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

Если cookie содержит чувствительную информацию (например, auth_token), важно защитить его от доступа через JavaScript. Иначе злоумышленник может украсть его через XSS-атаку (Cross-Site Scripting).

🟠Используем флаг `HttpOnly` (основная защита)
HttpOnly делает cookie недоступным для JavaScript (document.cookie).
Set-Cookie: auth_token=abc123; HttpOnly; Secure; SameSite=Strict


🟠Используем `Secure`, чтобы cookie передавались только по HTTPS
Флаг Secure запрещает передачу cookie через HTTP, только HTTPS.
Set-Cookie: auth_token=abc123; Secure


🟠Используем `SameSite`, чтобы защититься от CSRF-атак
SameSite=Strict или SameSite=Lax защищает от подделки запросов (CSRF).
Set-Cookie: auth_token=abc123; SameSite=Strict


🟠Не храним токены в cookie (если можно)
Если возможно, используйте Authorization: Bearer заголовки вместо cookie.
Authorization: Bearer abc123


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12💊3
🤔 В чём отличие null от undefined?

null в JavaScript — это явное указание на отсутствие значения или объекта, тогда как undefined означает, что переменная или свойство были объявлены, но не инициализированы. null назначается вручную разработчиком, а undefined — результат автоматического присваивания переменным, которые ещё не получили значения. В логическом контексте оба значения считаются ложными, но их использование отличается в зависимости от смысла кода. null чаще используется для инициализации переменных, ожидающих объект.

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

В контексте Frontend-разработки, dispatch — это метод, который отправляет (диспатчит) событие или действие. В зависимости от технологии dispatch может использоваться в Redux, EventTarget или React.

🟠`dispatch` в Redux
В Redux dispatch(action) используется для отправки (диспатча) действий (actions) в хранилище (store).
import { useDispatch } from 'react-redux';

const Counter = () => {
const dispatch = useDispatch();

return (
<button onClick={() => dispatch({ type: 'INCREMENT' })}>
Увеличить
</button>
);
};


🟠`dispatchEvent` в JavaScript (EventTarget API)
В нативном JavaScript метод dispatchEvent() используется для генерации пользовательских событий на DOM-элементах.
const button = document.querySelector("button");

// Создаём событие
const event = new Event("myCustomEvent");

// Добавляем слушатель событий
button.addEventListener("myCustomEvent", () => {
console.log("Событие вызвано!");
});

// Диспатчим событие
button.dispatchEvent(event); // Выведет: "Событие вызвано!"


🟠`dispatch` в React (useReducer)
В React-хуке useReducer dispatch используется для изменения состояния компонента.
import { useReducer } from 'react';

const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
default:
return state;
}
};

const Counter = () => {
const [state, dispatch] = useReducer(reducer, { count: 0 });

return (
<button onClick={() => dispatch({ type: 'increment' })}>
{state.count}
</button>
);
};


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

Можно, но только по смыслу:
- В HTML5 допустимо несколько h1 — по одному на секцию или article.
- Главное — сохранять логичную иерархию.


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

Замыкание и область видимости — это два фундаментальных концепта в 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
👍8💊4🔥2
🤔 Что означают union и intersection в TypeScript?

- Union (|): переменная может быть одного из указанных типов.
Пример: type A = string | number
- Intersection (&): переменная должна соответствовать всем типам сразу.
Пример: type B = { name: string } & { age: number }


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

Если в HTML-документе будет невалидная разметка, браузер всё равно попытается её обработать и отобразить страницу, но возможны различные неожиданные ошибки и баги. Давайте разберём, что может пойти не так.

🚩Что делает браузер с невалидным HTML?

Когда браузер сталкивается с ошибками в разметке, он использует механизм исправления ошибок (HTML Parser Error Handling). Это означает, что:
Браузер автоматически исправит некоторые ошибки (например, добавит закрывающий тег).
Некоторые элементы могут быть проигнорированы или отображены некорректно.
CSS и JavaScript могут работать неправильно из-за ошибки в DOM-структуре.

🚩Примеры ошибок и их последствия

Отсутствие закрывающего тега
<p>Привет, мир!
<p>Это новый абзац?


Вложенность тегов в неправильных местах
<p>Текст <div>Блок внутри абзаца</div></p>


По спецификации <div> нельзя вкладывать в <p>, браузер может вынести <div> за пределы абзаца.
Итоговый HTML может быть таким:
<p>Текст </p>
<div>Блок внутри абзаца</div>


🟠Отсутствие `DOCTYPE`
Если не указать <!DOCTYPE html>, браузер может перейти в режим совместимости (Quirks Mode), что приведёт к некорректному отображению стилей.
Неправильные атрибуты в тегах
<img src="image.jpg" alt="Картинка" wrongAttr="что это?">


Незакрытые теги в таблице
<table>
<tr>
<td>Ячейка 1
<td>Ячейка 2
</tr>
</table>


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9💊2
🤔 Зачем нужен механизм двустороннего связывания?

Two-way binding нужен для:
- синхронизации состояния UI и данных без дополнительного кода;
- удобной работы с формами и интерактивными компонентами;
- упрощения кода (особенно в v-model, ngModel).
Но может затруднять отладку и контроль, если применять безмерно.


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

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

🚩Как работают статические методы? (`static`)

В классе статические методы объявляются с помощью static. Они не находятся в prototype, а принадлежат самому классу.
class User {
static sayHello() {
return "Привет!";
}
}

console.log(User.sayHello()); // "Привет!"
console.log(User.prototype.sayHello); // undefined (нет в prototype)


🚩Добавление "статического" метода в `prototype` (не совсем статический)

Если нужно, чтобы каждый объект имел доступ к "статическому" методу через prototype, можно сделать так
function User(name) {
this.name = name;
}

// Добавляем метод в prototype
User.prototype.sayHello = function () {
return "Привет!";
};

const user1 = new User("Иван");
console.log(user1.sayHello()); // "Привет!"


🚩Добавление метода напрямую в сам класс (имитация `static`)

Если хочется добавить метод на сам класс, а не в prototype, можно сделать так
function User(name) {
this.name = name;
}

// Добавляем метод прямо в функцию-конструктор
User.sayHello = function () {
return "Привет!";
};

console.log(User.sayHello()); // "Привет!"


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊6👍5
🤔 Какой способ помогает бороться с прокидыванием, помимо Redux?

Можно использовать Context API, который позволяет передавать данные от родителя к потомку без явного прокидывания через props. Это удобно для глобальных данных: темы, язык, текущий пользователь.


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

Запросы к серверу в React можно выполнять в нескольких местах в зависимости от архитектуры вашего приложения и используемого подхода.

🚩Использование хуков

useEffect позволяет выполнять побочные эффекты, такие как запросы к серверу, в функциональных компонентах.
import React, { useState, useEffect } from 'react';

function DataFetchingComponent() {
const [data, setData] = useState(null);

useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
} catch (error) {
console.error('Error fetching data:', error);
}
};

fetchData();
}, []); // Пустой массив означает, что эффект выполнится только при монтировании компонента

return (
<div>
{data ? (
<pre>{JSON.stringify(data, null, 2)}</pre>
) : (
<p>Loading data...</p>
)}
</div>
);
}

export default DataFetchingComponent;


🚩Методы жизненного цикла в классовых компонентах

Метод componentDidMount используется для выполнения запросов к серверу в классовых компонентах после монтирования компонента.
import React, { Component } from 'react';

class DataFetchingComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: null,
};
}

componentDidMount() {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
this.setState({ data });
})
.catch(error => {
console.error('Error fetching data:', error);
});
}

render() {
const { data } = this.state;
return (
<div>
{data ? (
<pre>{JSON.stringify(data, null, 2)}</pre>
) : (
<p>Loading data...</p>
)}
</div>
);
}
}

export default DataFetchingComponent;


🟠Сервисы или утилиты
Запросы к серверу можно изолировать в отдельные файлы сервисов или утилит, что помогает сделать код более модульным и переиспользуемым.
service.js
export async function fetchData() {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
}


DataFetchingComponent.js
import React, { useState, useEffect } from 'react';
import { fetchData } from './service';

function DataFetchingComponent() {
const [data, setData] = useState(null);

useEffect(() => {
fetchData()
.then(data => setData(data))
.catch(error => console.error('Error fetching data:', error));
}, []);

return (
<div>
{data ? (
<pre>{JSON.stringify(data, null, 2)}</pre>
) : (
<p>Loading data...</p>
)}
</div>
);
}

export default DataFetchingComponent;


🟠Управление состоянием
Для крупных приложений, где важно централизованное управление состоянием, запросы к серверу можно выполнять в рамках таких библиотек, как Redux или MobX.

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

IIFE (Immediately Invoked Function Expression) — это функция в JavaScript, которая вызывается сразу после определения. Она используется для создания изолированного пространства имён, чтобы избежать конфликтов в глобальной области видимости.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍5
🤔 Зачем нужен 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 https://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 https://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
👍5