В чем отличие фреймворка от библиотеки (приведите примеры и отличия)?
|
Библиотека решает отдельную задачу, а приложение само определяет архитектуру и момент вызова библиотеки. Примеры: RxJS, Lodash, date-fns. Фреймворк задает каркас приложения, жизненный цикл, правила организации кода и сам вызывает пользовательский код в нужный момент. Это называют inversion of control. Примеры: Angular, NestJS. Angular предоставляет не только рендеринг, но и DI, Router, формы, HTTP-клиент, компиляцию шаблонов, CLI и инструменты тестирования. Поэтому Angular является платформой и фреймворком, а не просто UI-библиотекой. |
Какие популярные CSS, JS библиотеки вы знаете?
|
Примеры, которые уместно назвать вместе с их назначением:
На собеседовании важнее объяснить, какую проблему решает библиотека и почему она была выбрана, чем перечислить много названий. |
Что такое SOLID?
|
SOLID - пять принципов проектирования:
На практике SOLID помогает уменьшить связанность и упростить тестирование. Это ориентиры, а не требование создавать отдельный класс для каждой функции. |
Что такое DRY?
|
DRY означает, что одно бизнес-правило должно иметь один источник истины. Если порог бесплатной доставки используется в нескольких местах, его лучше вынести в общую функцию или доменный сервис. Одинаковые строки кода не всегда являются дублированием: два похожих сценария можно оставить раздельными, если они меняются по разным причинам. |
Что такое KISS?
|
KISS предлагает выбирать самое простое решение, которое корректно выполняет текущие требования. Если обычной функции или небольшого компонента достаточно, не нужны фабрики, глубокое наследование и универсальная конфигурация. Простота не отменяет типизацию, обработку ошибок и тесты. |
Что такое YAGNI?
|
YAGNI означает: не реализовывать функциональность, пока для нее нет подтвержденной потребности. Код «на будущее» увеличивает объем поддержки и часто основан на неверном прогнозе. При этом текущее решение должно оставаться понятным и допускать безопасные изменения. |
Как могут конфликтовать SOLID, DRY, KISS и YAGNI?
|
Принципы могут подталкивать к разным решениям:
Приоритет отдают текущим требованиям и стоимости изменений. Сначала пишут ясное рабочее решение, а абстракцию добавляют после появления устойчивого повторения или вариативности. |
Как применять инженерные принципы в Angular?
export interface UserRepository {
findById(id: string): Observable<User>;
}
export const USER_REPOSITORY = new InjectionToken<UserRepository>('USER_REPOSITORY');
@Injectable({providedIn: 'root'})
export class UserFacade {
private readonly repository = inject(USER_REPOSITORY);
load(id: string): Observable<User> {
return this.repository.findById(id);
}
}
|
Что такое cohesion и coupling?
|
Cohesion показывает, насколько логика внутри модуля относится к одной задаче. Coupling показывает, насколько сильно модуль зависит от деталей других модулей. Обычно стремятся к высокой cohesion и низкому явному coupling: например, состояние корзины и расчет суммы можно хранить вместе, а аналитику и HTTP вынести за ее границы. |
Что лучше: композиция или наследование?
|
Во frontend чаще выбирают композицию: компоненты, сервисы, директивы, content projection, host directives и DI можно сочетать без глубокой иерархии классов. Наследование уместно, когда существует устойчивое отношение «является» и подкласс полностью соблюдает контракт базового типа. |
Что такое code smell и technical debt?
|
Code smell - признак возможной проблемы дизайна: большой компонент, длинный список зависимостей, boolean-флаги с противоречивыми состояниями или повторение бизнес-правил. Technical debt - будущая стоимость сделанного упрощения. Он допустим как осознанный компромисс с ограниченным риском, тестовой страховкой и планом пересмотра. |
Что такое рефакторинг?
|
Рефакторинг улучшает внутреннюю структуру кода без изменения наблюдаемого поведения. Его выполняют небольшими шагами под тестами. Если небольшое бизнес-правило нельзя проверить без большого |
Что такое функциональное программирование?
|
Функциональное программирование строит вычисления вокруг функций и преобразований данных. Практические идеи:
Во frontend это упрощает тестирование и предсказуемость состояния. Полностью избегать мутаций не обязательно: важно локализовать их на понятных границах. |
Назовите основные принципы ООП?
ООП не требует применять наследование везде. В Angular чаще полезны композиция компонентов и сервисов, DI и небольшие интерфейсы. Пример сочетает четыре принципа: interface NotificationChannel {
send(message: string): void;
}
abstract class BaseNotificationChannel implements NotificationChannel {
constructor(private readonly prefix: string) {}
protected format(message: string): string {
return `${this.prefix}: ${message}`;
}
abstract send(message: string): void;
}
class EmailChannel extends BaseNotificationChannel {
send(message: string): void {
sendEmail(this.format(message));
}
}
class PushChannel extends BaseNotificationChannel {
send(message: string): void {
sendPush(this.format(message));
}
}
function notify(channel: NotificationChannel, message: string): void {
channel.send(message);
}
Отдельно часто спрашивают SOLID: пять принципов проектирования, которые помогают уменьшать связанность и делать код расширяемым и тестируемым. |
Sequence diagram / диаграмма последовательности
Что такое sequence diagram и для чего она нужна?
|
Sequence diagram показывает, как участники системы обмениваются сообщениями во времени. Она помогает разобрать порядок вызовов, границы ответственности, async flows, ошибки и интеграции между frontend, backend и внешними сервисами. |
Чем sequence diagram отличается от flowchart?
|
Sequence diagram фокусируется на взаимодействии участников и порядке сообщений между ними. Flowchart фокусируется на ветвлениях, шагах алгоритма и принятии решений внутри процесса. |
Что такое participant, lifeline, message и response?
|
Participant - участник сценария, например Component, Service, Interceptor или Backend. Lifeline - вертикальная линия жизни участника во времени. Message - вызов или событие между участниками. Response - ответ на вызов или результат обработки. |
Почему sequence diagram читается сверху вниз?
|
Вертикальная ось показывает ход времени: верхние сообщения происходят раньше нижних. Поэтому порядок строк важен и позволяет увидеть, что произошло до запроса, после ответа, при ошибке или повторной попытке. |
Как на sequence diagram показать синхронный вызов, асинхронное сообщение и ответ?
|
Обычно синхронный вызов показывают сплошной стрелкой, асинхронное сообщение - отдельной нотацией инструмента, а ответ - обратной пунктирной стрелкой. Важно не столько оформление стрелки, сколько явный порядок: кто вызывает, кого вызывает и когда получает результат. sequenceDiagram
Component->>Service: load()
Service-->>Component: data
|
Как показать альтернативные сценарии: success / error, cache hit / cache miss?
|
Альтернативы показывают через блоки sequenceDiagram
Component->>Service: load()
alt cache hit
Service-->>Component: cached data
else cache miss
Service->>Backend: GET /items
Backend-->>Service: items
end
|
Как показать retry, timeout или fallback?
|
Retry удобно показывать через sequenceDiagram
Component->>Service: load()
loop up to 3 attempts
Service->>Backend: GET /items
Backend-->>Service: timeout
end
Service-->>Component: fallback data
|
Когда sequence diagram полезна frontend-разработчику?
|
Она полезна при разборе авторизации, refresh token flow, загрузки данных, race conditions, optimistic updates, interceptors, guards, WebSocket-сценариев и взаимодействия нескольких сервисов. Диаграмма быстро показывает, где живет логика и какие ошибки нужно обработать. |
Какие признаки плохой или перегруженной sequence diagram?
|
Слишком много участников, смешение нескольких независимых сценариев, отсутствие условий, неясные названия сообщений, детали реализации вместо бизнес-событий и попытка показать всю систему на одной диаграмме. Хорошая диаграмма отвечает на один конкретный вопрос. |
Нарисуйте sequence diagram для сценария refresh token в Angular.
sequenceDiagram
participant Component
participant Service
participant Interceptor
participant Backend
Component->>Service: loadData()
Service->>Interceptor: HTTP request
Interceptor->>Backend: request with access token
Backend-->>Interceptor: 401
Interceptor->>Backend: refresh token
Backend-->>Interceptor: new access token
Interceptor->>Backend: retry original request
Backend-->>Interceptor: data
Interceptor-->>Service: data
Service-->>Component: data
В ответе важно показать, что refresh выполняет interceptor, исходный запрос повторяется после получения нового access token, а component получает результат как обычный ответ сервиса. |
Flowchart / блок-схема
Что такое flowchart и для чего она нужна?
|
Flowchart, или блок-схема, показывает шаги процесса, условия и переходы между ними. Она помогает обсудить алгоритм, валидацию, бизнес-правила или decision tree без привязки к конкретному коду. |
Чем flowchart отличается от sequence diagram?
|
Flowchart отвечает на вопрос "какие шаги и условия есть в процессе". Sequence diagram отвечает на вопрос "какие участники обмениваются сообщениями и в каком порядке". |
Какие базовые элементы flowchart вы знаете: start/end, process, decision, input/output?
|
Start/end обозначает начало и завершение процесса. Process - действие или вычисление. Decision - условие с несколькими ветками. Input/output - получение входных данных или вывод результата. |
Как на flowchart показать условие if/else?
|
Условие показывают decision-блоком с двумя или несколькими исходящими ветками. Ветки подписывают значениями условия,
например flowchart TD
A[Start] --> B{User authorized?}
B -->|yes| C[Show content]
B -->|no| D[Show login]
|
Как на flowchart показать цикл?
|
Цикл показывают обратной связью к предыдущему шагу или условию. Важно подписать условие продолжения и условие выхода, иначе схема превращается в неясное повторение. flowchart TD
A[Take next item] --> B{Has item?}
B -->|yes| C[Process item]
C --> A
B -->|no| D[Finish]
|
Когда flowchart лучше подходит, чем sequence diagram?
|
Flowchart лучше подходит для условий, алгоритмов, валидации формы, расчета статуса, показа UI-состояний и бизнес-правил, где важнее decision logic, чем обмен сообщениями между несколькими участниками. |
Как flowchart помогает разобрать сложную бизнес-логику?
|
Она делает явными входные данные, порядок проверок, причины отказа, крайние случаи и дублирующиеся условия. По такой схеме проще договориться с аналитиком, backend и QA до написания кода. |
Какие проблемы появляются, если пытаться описать слишком большую систему одной flowchart?
|
Схема становится нечитаемой: слишком много веток, пересечений, уровней детализации и скрытых правил. Лучше разделять ее на несколько схем: общий happy path, ошибки, отдельные доменные процессы и редкие edge cases. |
Нарисуйте flowchart для логики показа кнопки "Купить".
flowchart TD
A[Start] --> B{User authorized?}
B -->|no| C[Show reason: login required]
B -->|yes| D{Product in stock?}
D -->|no| E[Show reason: out of stock]
D -->|yes| F{User not blocked?}
F -->|no| G[Show reason: user blocked]
F -->|yes| H{Delivery available?}
H -->|no| I[Show reason: delivery unavailable]
H -->|yes| J[Show enabled Buy button]
Хороший ответ показывает не только итог |
ER diagram / Entity Relationship Diagram
Что такое ER diagram и для чего она нужна?
|
ER diagram показывает сущности предметной области, их поля и связи. Она помогает понять структуру данных, ограничения, отношения между объектами и то, как эти данные могут приходить во frontend через API. |
Чем entity отличается от table?
|
Entity - сущность предметной области, например User или Booking. Table - конкретное хранение этой сущности в базе данных. В простой системе они могут почти совпадать, но entity описывает смысл, а table - техническую реализацию. |
Что такое attribute / field?
|
Attribute или field - свойство сущности: |
Что такое primary key?
|
Primary key - поле или набор полей, которые уникально идентифицируют запись. Для frontend это часто стабильный |
Что такое foreign key?
|
Foreign key - поле, которое ссылается на primary key другой сущности. Например, |
Какие бывают связи между сущностями: one-to-one, one-to-many, many-to-many?
|
One-to-one: одной записи соответствует одна другая запись. One-to-many: одна запись связана со многими, например Movie и Sessions. Many-to-many: многие записи связаны со многими, например Users и Roles или Students и Courses. |
Как смоделировать many-to-many связь?
|
Many-to-many обычно моделируют через отдельную связующую сущность. Она хранит ссылки на обе стороны связи и может иметь собственные поля: дату создания, статус, порядок, роль или цену. |
Что такое junction table / linking table?
|
Junction table, или linking table, - таблица-связка для many-to-many. Например, |
Почему frontend-разработчику полезно понимать ER diagrams?
|
Так проще понимать API, нормализовать данные, проектировать state, ловить неоднозначности в DTO и задавать backend правильные вопросы. ER diagram помогает увидеть, какие данные являются справочниками, какие зависят от пользователя, а какие являются результатом операции. |
Как ER diagram помогает понять API и структуру данных на frontend?
|
Она показывает, какие объекты могут приходить вложенными, где нужны ids, какие связи надо дозагружать и какие поля нельзя редактировать напрямую. Это влияет на типы DTO, формы, кеширование, optimistic updates и normalized stores. |
Чем ER diagram отличается от class diagram?
|
ER diagram описывает данные и связи предметной области. Class diagram описывает классы, методы, наследование, интерфейсы и объектную модель кода. Они могут пересекаться по названиям сущностей, но отвечают на разные вопросы. |
Нарисуйте ER diagram для простой системы бронирования билетов в кино.
erDiagram
User ||--o{ Booking : creates
Movie ||--o{ Session : has
Session ||--o{ Seat : contains
Session ||--o{ Booking : booked_for
Booking ||--o{ Seat : reserves
Booking ||--o| Payment : paid_by
User {
string id
string email
}
Movie {
string id
string title
}
Session {
string id
string movieId
datetime startsAt
}
Seat {
string id
string sessionId
string row
string number
}
Booking {
string id
string userId
string sessionId
string status
}
Payment {
string id
string bookingId
string status
}
На собеседовании можно обсудить, нужна ли отдельная сущность |
Инструменты
Какие инструменты можно использовать для описания диаграмм в документации: Mermaid, PlantUML, draw.io / diagrams.net?
|
Mermaid и PlantUML описывают диаграммы текстом, поэтому хорошо подходят для version control и code review. draw.io / diagrams.net удобен для визуального редактирования, особенно когда нужна свободная компоновка или схема для презентации. |
Почему Mermaid удобно использовать в GitHub README?
|
GitHub умеет рендерить Mermaid прямо в Markdown. Диаграмма хранится как текст рядом с документацией, ее легко читать в diff, ревьюить, менять вместе с кодом и поддерживать без отдельных бинарных файлов. |
Что такое сложность алгоритмов?
|
Big O показывает верхнюю асимптотическую границу роста времени или памяти при увеличении входных данных. Константы и небольшие слагаемые обычно отбрасывают.
Один цикл по |
Чем Θ-нотация отличается от O-нотации?
|
Например, полный проход по массиву всегда выполняет пропорциональное |
Как измерять сложность алгоритма?
|
Определяют размер входа Помимо времени учитывают память, реальные размеры данных и стоимость операций. Профилирование дополняет асимптотическую оценку: алгоритм с лучшим Big O не всегда быстрее на маленьком входе. |
Как оптимизировать перебор двумя циклами?
|
Часто один набор заранее индексируют через const usersById = new Map(users.map((user) => [user.id, user]));
const ordersWithUsers = orders.map((order) => ({
...order,
user: usersById.get(order.userId),
}));Вместо примерно |
Чем линейный поиск отличается от бинарного?
|
Линейный поиск проверяет элементы последовательно и работает за Бинарный поиск делит область поиска пополам и работает за |
Какова сложность доступа в основных структурах данных?
В JavaScript для очереди частый |
Какой алгоритм сортировки полезно знать?
|
Merge sort делит массив пополам, сортирует части и сливает их. Временная сложность - В прикладном frontend-коде обычно используют встроенный |
Что такое структура данных и какие виды вы знаете (Стек, etc)?
|
Структура данных — способ организовать данные и операции над ними.
На собеседовании полезно сравнить сложность основных операций по времени и памяти, а не только дать определения. |
Как следить за чистотой кода?
|
Помогают небольшие функции, точные имена, строгие типы, явные состояния, отсутствие скрытых side effects и регулярное удаление мертвого кода. ESLint, Prettier и тесты автоматизируют проверки, но не заменяют ясные границы модулей и ответственность разработчика. |



