master
pavel 4 months ago
commit 4abcf76ee2

File diff suppressed because it is too large Load Diff

@ -0,0 +1,756 @@
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
## 1. `Каковы различия между декоратором Angular и аннотацией?`
Декораторы и аннотации в Angular имеют различные функции и синтаксис.
Декораторы в Angular используются для добавления метаданных к классам, методам, свойствам и параметрам. Они представляют собой специальные функции, которые применяются к элементам кода с помощью символа @. Декораторы позволяют определить различные аспекты поведения и конфигурации элементов Angular, таких как компоненты, сервисы, директивы и т. д. Некоторые из наиболее часто используемых декораторов в Angular включают @Component, @Directive, @Injectable и @Input.
Аннотации в Angular, с другой стороны, являются способом добавления дополнительной информации к типам данных в TypeScript. Аннотации используются для определения типов параметров функций, свойств классов и других элементов кода. Они представляют собой специальные комментарии, которые начинаются с символа @. Аннотации в Angular используются вместе с декораторами для определения типов данных и метаданных элементов Angular.
Таким образом, различия между декораторами и аннотациями в Angular заключаются в их функциональности и синтаксисе. Декораторы используются для добавления метаданных к элементам Angular, в то время как аннотации используются для определения типов данных в TypeScript.
## 2. `Что такое AOT-компиляция в Angular (Ahead-of-Time компиляция)?`
AOT-компиляция (Ahead-of-Time компиляция) в Angular - это процесс преобразования кода Angular HTML и TypeScript в эффективный JavaScript-код во время этапа сборки перед запуском в браузере
Основное отличие AOT-компиляции от JIT-компиляции (Just-in-Time компиляции) заключается в том, что при AOT-компиляции код Angular преобразуется в JavaScript до запуска приложения, в то время как при JIT-компиляции преобразование происходит во время выполнения приложения в браузере.
Преимущества AOT-компиляции в Angular включают:
+ Улучшенную производительность: AOT-компиляция позволяет уменьшить размер и сложность кода, что приводит к более быстрой загрузке и выполнению приложения.
+ Более раннее обнаружение ошибок: AOT-компиляция позволяет обнаружить некоторые ошибки во время этапа сборки, что помогает предотвратить возможные проблемы во время выполнения приложения.
+ Улучшенную безопасность: AOT-компиляция позволяет обнаружить потенциальные уязвимости в коде на этапе сборки, что помогает улучшить безопасность приложения.
+ AOT-компиляция в Angular может быть выполнена с помощью Angular CLI, добавив флаг --aot при выполнении команды сборки, например: ng build --aot .
## 3. `Что такое динамические компоненты?`
Динамические компоненты в Angular позволяют создавать и добавлять компоненты в приложение во время выполнения. Они представляют собой способ генерации и управления компонентами динамически, без необходимости определения их статически в шаблоне.
Для создания динамических компонентов в Angular используются методы createComponent() и ComponentFactoryResolver. Метод createComponent() позволяет создавать экземпляры компонентов, а ComponentFactoryResolver используется для получения фабрики компонента, которую можно использовать для создания экземпляров компонента.
Пример использования динамических компонентов в Angular:
```javascript
import { Component, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core';
@Component({
template: `<div><ng-container #dynamicContent></ng-container></div>`,
})
export class AppComponent {
@ViewChild("dynamicContent", { read: ViewContainerRef })
public dynamicContainer: ViewContainerRef;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
createDynamicComponent() {
// Получение фабрики компонента
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(DynamicComponent);
// Создание экземпляра компонента
const componentRef = this.dynamicContainer.createComponent(componentFactory);
}
}
```
В приведенном примере AppComponent содержит ViewContainerRef, который представляет контейнер для динамически создаваемых компонентов. Метод createDynamicComponent() использует ComponentFactoryResolver для получения фабрики компонента DynamicComponent, а затем создает экземпляр компонента с помощью createComponent().
Важно отметить, что динамические компоненты в Angular могут быть полезны при создании динамических макетов, модальных окон, компонентов, которые должны быть добавлены или удалены в зависимости от условий, и других сценариев, требующих гибкости и динамического управления компонентами.
## 4. `Что такое модули в Angular?`
Модули в Angular - это способ организации и структурирования приложения на Angular. Модули позволяют разделить функциональность приложения на отдельные блоки, называемые модулями. Каждый модуль содержит компоненты, сервисы, директивы и другие ресурсы, связанные с определенной функциональностью приложения.
Модули в Angular предоставляют следующие преимущества:
Логическая организация: Модули позволяют разделить функциональность приложения на логические блоки, что делает код более понятным и поддерживаемым.
Изоляция: Каждый модуль имеет свою собственную область видимости, что позволяет изолировать компоненты и сервисы от других частей приложения.
Ленивая загрузка: Модули могут быть загружены только по требованию, что улучшает производительность приложения и уменьшает время загрузки.
Переиспользование: Модули могут быть повторно использованы в разных приложениях или в разных частях одного приложения.
NgModule - это декоратор, который используется для определения модуля в Angular. Он применяется к классу модуля и принимает объект конфигурации, который определяет компоненты, сервисы и другие ресурсы, связанные с модулем.
Пример использования декоратора NgModule:
```javascript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
```
В приведенном примере AppModule является корневым модулем приложения. Он импортирует BrowserModule, который предоставляет функциональность для работы с браузером, и объявляет AppComponent в качестве компонента, который будет использоваться в модуле.
## 5. `Что такое сервисы в Angular?`
Сервисы в Angular - это классы, которые предоставляют функциональность и могут быть использованы в разных частях приложения. Они используются для разделения логики и общих функций между компонентами, директивами и другими классами Angular.
Сервисы в Angular обычно используются для выполнения следующих задач:
Получение данных с сервера или других источников данных.
Хранение и обработка данных, которые должны быть доступны в разных частях приложения.
Реализация общей функциональности, такой как аутентификация, логирование и обработка ошибок.
Взаимодействие с внешними библиотеками или сервисами.
Сервисы в Angular могут быть созданы с помощью ключевого слова @Injectable и зарегистрированы в модуле приложения или компоненте с помощью массива providers. Это позволяет Angular создавать и предоставлять экземпляр сервиса внедрения зависимостей (DI) при создании компонента или другого класса.
Пример регистрации сервиса в модуле Angular:
```javascript
import { NgModule } from '@angular/core';
import { MyService } from './my.service';
@NgModule({
providers: [MyService]
})
export class AppModule { }
```
После регистрации сервиса в модуле, он может быть внедрен в компоненты или другие классы, используя DI. Например, в компоненте можно внедрить сервис следующим образом:
```javascript
import { Component } from '@angular/core';
import { MyService } from './my.service';
@Component({
selector: 'app-my-component',
template: '...',
})
export class MyComponent {
constructor(private myService: MyService) { }
}
```
Важно отметить, что сервисы в Angular могут быть созданы в разных режимах жизненного цикла, таких как синглтон, когда создается только один экземпляр сервиса на всё приложение, или новый экземпляр сервиса для каждого компонента. Выбор режима жизненного цикла зависит от требований и особенностей приложения.
## 6. `Что такое жизненный цикл компонента в Angular?`
Жизненный цикл компонента в Angular - это последовательность событий и методов, которые происходят при создании, обновлении и уничтожении компонента в Angular. Жизненный цикл компонента предоставляет разработчикам возможность выполнять определенные действия на разных этапах жизненного цикла компонента, таких как инициализация, обновление и уничтожение.
Методы жизненного цикла компонента в Angular
В Angular есть несколько методов жизненного цикла компонента, которые разработчики могут использовать для выполнения определенных действий на разных этапах жизненного цикла компонента. Некоторые из этих методов включают:
+ ngOnChanges: Этот метод вызывается, когда значения входных свойств компонента изменяются. Он принимает объект SimpleChanges, который содержит информацию о предыдущих и текущих значениях входных свойств..
+ ngOnInit: Этот метод вызывается после того, как Angular инициализирует компонент и устанавливает входные свойства. Он используется для выполнения инициализационных действий, таких как получение данных с сервера или настройка компонента..
+ ngDoCheck: Этот метод вызывается при каждом изменении в компоненте, включая изменения входных свойств, события и обнаружение изменений, которые Angular не может обнаружить самостоятельно. Он позволяет разработчикам выполнять дополнительные проверки и действия при изменении компонента..
+ ngAfterContentInit: Этот метод вызывается после того, как Angular вставляет внешний контент в представление компонента. Он используется для выполнения действий, которые требуют доступа к внешнему контенту, например, инициализация дочерних компонентов..
+ ngAfterContentChecked: Этот метод вызывается после каждой проверки внешнего контента компонента. Он используется для выполнения действий, которые требуют доступа к внешнему контенту и проверки его изменений..
+ ngAfterViewInit: Этот метод вызывается после инициализации представления компонента и его дочерних компонентов. Он используется для выполнения действий, которые требуют доступа к представлению компонента, например, инициализация сторонних библиотек или установка обработчиков событий..
+ ngAfterViewChecked: Этот метод вызывается после каждой проверки представления компонента и его дочерних компонентов. Он используется для выполнения действий, которые требуют доступа к представлению компонента и проверки его изменений..
+ ngOnDestroy: Этот метод вызывается перед уничтожением компонента. Он используется для выполнения действий, таких как отписка от подписок, очистка ресурсов или отмена запущенных процессов..
Пример использования методов жизненного цикла компонента в Angular:
```javascript
import { Component, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-my-component',
template: `
<h1>{{ title }}</h1>
`
})
export class MyComponent implements OnInit, OnDestroy {
title: string;
ngOnInit() {
this.title = 'Hello, Angular!';
console.log('Component initialized');
}
ngOnDestroy() {
console.log('Component destroyed');
}
}
```
В приведенном выше примере компонент MyComponent реализует интерфейсы OnInit и OnDestroy, что позволяет использовать методы ngOnInit и ngOnDestroy. В методе ngOnInit устанавливается значение переменной title и выводится сообщение в консоль при инициализации компонента. В методе ngOnDestroy выводится сообщение в консоль перед уничтожением компонента.
Обратите внимание: При использовании методов жизненного цикла компонента в Angular, важно следить за правильным использованием и избегать выполнения длительных операций в методах, которые могут замедлить работу приложения.
## 8. `Чем наблюдаемые отличаются от обещаний?`
В Angular, наблюдаемые (observables) и обещания (promises) являются двумя разными концепциями для работы с асинхронными операциями. Вот некоторые основные различия между ними:
Наблюдаемые (observables):
+ Наблюдаемые представляют собой поток данных, который может иметь несколько значений, передаваемых по мере их поступления.
+ Они поддерживают операторы, такие как map, filter, reduce и другие, которые позволяют манипулировать данными в потоке.
+ Наблюдаемые могут быть отменены или отписаны с помощью метода unsubscribe.
+ Они широко используются в Angular для работы с асинхронными операциями, такими как HTTP-запросы или события пользовательского интерфейса.
Обещания (promises):
+ Обещания представляют собой единственное значение, которое будет доступно в будущем, либо успешно, либо с ошибкой.
+ Они поддерживают методы, такие как then, catch, finally, которые позволяют обрабатывать успешное выполнение, ошибку или выполнение в любом случае.
+ Обещания не могут быть отменены или отписаны после того, как они были выполнены.
+ Они также широко используются в Angular для работы с асинхронными операциями, но наблюдаемые предпочтительнее в некоторых случаях, особенно когда нужно работать с потоками данных.
Таким образом, основные различия между наблюдаемыми и обещаниями в Angular заключаются в том, что наблюдаемые представляют собой поток данных с возможностью манипуляции, отмены и отписки, в то время как обещания представляют собой единственное значение, которое будет доступно в будущем.
## 9. `Что такое бутстрэппинг?`
Бутстрэппинг в Angular - это процесс инициализации и запуска приложения Angular. Во время бутстрэппинга Angular создает корневой компонент приложения и связывает его с DOM-элементом на странице. Затем Angular загружает и компилирует компоненты, устанавливает связи между компонентами и их шаблонами, и запускает приложение.
В процессе бутстрэппинга Angular также устанавливает связь между компонентами и сервисами, провайдерами и другими зависимостями, которые могут быть необходимы для работы приложения.
Бутстрэппинг в Angular обычно выполняется в файле main.ts, где вызывается функция platformBrowserDynamic().bootstrapModule(AppModule), где AppModule - это модуль приложения, который содержит корневой компонент и другие компоненты, сервисы и зависимости.
Пример кода:
```javascript
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
```
В этом примере AppModule - это модуль приложения, который содержит корневой компонент и другие компоненты, сервисы и зависимости. Функция platformBrowserDynamic().bootstrapModule(AppModule) запускает процесс бутстрэппинга, и Angular начинает загружать и компилировать компоненты, устанавливать связи и запускать приложение.
## 10. `Что вы подразумеваете под внедрением зависимостей?`
Angular - это платформа для разработки веб-приложений, которая позволяет создавать масштабируемые и эффективные приложения с использованием компонентной архитектуры. Внедрение зависимостей (Dependency Injection, DI) является одним из ключевых концепций в Angular.
Под внедрением зависимостей в Angular подразумевается механизм, который позволяет компонентам и сервисам получать необходимые им зависимости извне, вместо того, чтобы создавать их самостоятельно. Это позволяет создавать слабосвязанные компоненты и сервисы, что упрощает тестирование, повторное использование кода и обеспечивает более гибкую архитектуру приложения.
Когда компонент или сервис требует определенную зависимость, Angular автоматически создает экземпляр этой зависимости и предоставляет его внутри компонента или сервиса. Это позволяет избежать необходимости явного создания и управления зависимостями вручную.
Пример использования внедрения зависимостей в Angular:
```javascript
import { Component, Injectable } from '@angular/core';
@Injectable()
export class DataService {
getData(): string {
return 'Some data';
}
}
@Component({
selector: 'app-example',
template: `
<h1>{{ data }}</h1>
`,
})
export class ExampleComponent {
constructor(private dataService: DataService) {}
ngOnInit() {
this.data = this.dataService.getData();
}
}
```
В приведенном примере DataService является сервисом, который предоставляет данные. Компонент ExampleComponent требует эту зависимость и получает ее через конструктор. Angular автоматически создает экземпляр DataService и предоставляет его внутри ExampleComponent.
## 11. `Описать аутентификацию и авторизацию Angular.`
Аутентификация и авторизация являются важными аспектами разработки веб-приложений. В Angular есть несколько подходов к реализации аутентификации и авторизации, включая использование JSON Web Tokens (JWT) и HttpInterceptor.
Аутентификация с использованием JSON Web Tokens (JWT): JSON Web Tokens (JWT) - это открытый стандарт (RFC 7519), который определяет компактный и самодостаточный формат для представления информации об аутентификации в виде JSON-объекта. В Angular вы можете использовать JWT для аутентификации пользователей.
Для реализации аутентификации с использованием JWT в Angular, вам потребуется:
Создать серверную часть, которая будет генерировать и проверять JWT-токены.
Реализовать механизм хранения токена на клиентской стороне (например, в localStorage или sessionStorage).
Создать сервис аутентификации в Angular, который будет отправлять запросы на сервер для аутентификации и получения токена, а также сохранять и проверять токен на клиентской стороне.
Авторизация с использованием HttpInterceptor: HttpInterceptor - это механизм в Angular, который позволяет перехватывать и изменять HTTP-запросы и ответы. Вы можете использовать HttpInterceptor для авторизации запросов, добавляя заголовки авторизации или проверяя токены доступа.
Для реализации авторизации с использованием HttpInterceptor в Angular, вам потребуется:
+ Создать класс, реализующий интерфейс HttpInterceptor.
+ В классе HttpInterceptor реализовать методы для перехвата и изменения HTTP-запросов и ответов.
+ Зарегистрировать HttpInterceptor в провайдере приложения, чтобы он был доступен для использования во всем приложении.
Примеры кода:
+ Аутентификация с использованием JWT:
```javascript
// Сервис аутентификации
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class AuthService {
constructor(private http: HttpClient) {}
login(username: string, password: string) {
return this.http.post('/api/auth/login', { username, password });
}
}
// Компонент для входа пользователя
import { Component } from '@angular/core';
import { AuthService } from './auth.service';
@Component({
selector: 'app-login',
template: `
<form (ngSubmit)="login()">
<input type="text" [(ngModel)]="username" name="username" placeholder="Username">
<input type="password" [(ngModel)]="password" name="password" placeholder="Password">
<button type="submit">Login</button>
</form>
`,
})
export class LoginComponent {
username: string;
password: string;
constructor(private authService: AuthService) {}
login() {
this.authService.login(this.username, this.password).subscribe(
(response) => {
// Сохранение токена на клиентской стороне
localStorage.setItem('token', response.token);
},
(error) => {
console.error('Ошибка аутентификации:', error);
}
);
}
}
```
+ Авторизация с использованием HttpInterceptor:
```javascript
// HttpInterceptor
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Получение токена из localStorage
const token = localStorage.getItem('token');
// Добавление заголовка авторизации
if (token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
return next.handle(request);
}
}
// Регистрация HttpInterceptor в провайдере приложения
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';
@NgModule({
imports: [HttpClientModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
]
})
export class CoreModule {}
```
Обратите внимание: Это только примеры кода для демонстрации основных концепций аутентификации и авторизации в Angular. Реальная реализация может варьироваться в зависимости от требований вашего приложения.
## 12. `Что такое процесс цикла дайджеста в Angular?`
В Angular процесс цикла дайджеста (digest cycle) является ключевым механизмом для обновления данных и обновления представления. Во время цикла дайджеста Angular проверяет все связанные скоупы (scopes) и выполняет проверку изменений в данных. Если происходят изменения, Angular обновляет представление, чтобы отразить эти изменения.
Процесс цикла дайджеста в Angular состоит из следующих шагов:
+ Запуск цикла дайджеста: Цикл дайджеста запускается в ответ на событие, такое как пользовательское действие или изменение данных.
+ Проверка изменений: Angular проверяет все скоупы (scopes) и их модели данных на наличие изменений. Он сравнивает текущие значения с предыдущими значениями и определяет, какие из них изменились.
+ Применение изменений: Если Angular обнаруживает изменения в данных, он обновляет представление, чтобы отразить эти изменения. Это может включать обновление текста, добавление или удаление элементов DOM и другие изменения в пользовательском интерфейсе.
+ Проверка изменений вложенных скоупов: Angular также проверяет изменения во всех вложенных скоупах и их моделях данных.
+ Повторение цикла дайджеста: Цикл дайджеста повторяется до тех пор, пока не будет достигнуто состояние стабильности, то есть пока не будет обнаружено никаких изменений в данных или представлении.
Цикл дайджеста в Angular позволяет обеспечить синхронизацию данных и представления, что делает фреймворк мощным инструментом для разработки динамических веб-приложений.
## 13. `Что такое Angular Router?`
Angular Router - это сервис в Angular, который позволяет осуществлять навигацию между различными представлениями приложения. Он позволяет переходить от одного представления к другому в процессе выполнения пользовательских задач.
Angular Router предоставляет механизм для определения маршрутов и их связывания с компонентами приложения. Он позволяет определить, какой компонент должен быть отображен при переходе по определенному URL-адресу или при выполнении определенного действия пользователем.
Чтобы использовать Angular Router, необходимо импортировать соответствующие модули и классы. Например, для определения маршрутов и настройки маршрутизации в Angular, вы можете использовать классы Routes и RouterModule из модуля @angular/router.
Пример использования Angular Router для определения маршрутов выглядит следующим образом:
```javascript
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
```
В этом примере мы определяем три маршрута: 'home', 'about' и 'contact', и связываем каждый маршрут с соответствующим компонентом.
Angular Router также предоставляет множество других возможностей, таких как параметры маршрута, защита маршрутов, вложенные маршруты и многое другое. Он является важной частью разработки приложений на Angular и обеспечивает гибкую и мощную систему навигации внутри приложения.
## 14. `Что такое REST?`
REST API в Angular - это способ взаимодействия с сервером, используя протокол HTTP и стандартные методы запросов, такие как GET, POST, PUT и DELETE. В Angular, для работы с REST API, можно использовать сервис HttpClient, который предоставляет удобные методы для отправки HTTP-запросов и получения ответов от сервера.
REST API в Angular позволяет вам обмениваться данными с сервером и выполнять различные операции, такие как получение, создание, обновление и удаление данных. Он является важной частью разработки веб-приложений на Angular и позволяет создавать мощные и интерактивные приложения.
Обратите внимание, что RESTful API не является частью Angular-приложения. RESTful API - это веб-сервис, написанный на серверной стороне, который может использоваться Angular-приложением для взаимодействия с сервером
Для работы с REST API в Angular можно использовать модуль HttpClient, который предоставляет удобные методы для отправки HTTP-запросов и получения ответов. Вот некоторые основные шаги для работы с REST API в Angular:
+ Импортируйте модуль HttpClientModule в вашем Angular-приложении.
```javascript
import { HttpClientModule } from '@angular/common/http';
Добавьте HttpClientModule в раздел imports в файле AppModule.
@NgModule({
imports: [
HttpClientModule
],
// ...
})
export class AppModule { }
```
+ В вашем компоненте или сервисе импортируйте HttpClient и используйте его для отправки HTTP-запросов.
```javascript
import { HttpClient } from '@angular/common/http';
constructor(private http: HttpClient) { }
// Пример GET-запроса
getData() {
return this.http.get('https://api.example.com/data');
}
// Пример POST-запроса
postData(data: any) {
return this.http.post('https://api.example.com/data', data);
}
```
+ Вызовите методы getData() или postData() для отправки запросов и получения данных.
```javascript
this.getData().subscribe((response) => {
console.log(response);
}, (error) => {
console.error(error);
});
```
Примечание: Важно помнить, что HTTP-запросы асинхронны, поэтому для получения данных необходимо использовать методы подписки, такие как subscribe().
Это основные шаги для работы с REST API в Angular. Вы также можете использовать другие методы, такие как PUT и DELETE, для взаимодействия с API.
## 15. `Объясните Angular CLI.`
Angular CLI (Command Line Interface) - это инструмент командной строки, который предоставляет разработчикам возможность создавать, развивать и поддерживать проекты на Angular. Он предоставляет набор команд, которые упрощают различные задачи, связанные с разработкой Angular-приложений.
Основные возможности Angular CLI:
+ Создание нового проекта: Angular CLI позволяет создавать новые проекты с помощью команды ng new. Он автоматически настраивает структуру проекта, устанавливает зависимости и создает основные файлы и папки, необходимые для разработки Angular-приложения.
+ Генерация компонентов, сервисов и других элементов: Angular CLI предоставляет команды для генерации различных элементов приложения, таких как компоненты, сервисы, директивы и многое другое. Например, команда ng generate component my-component создаст новый компонент с именем "my-component" и соответствующими файлами и кодом.
+ Запуск локального сервера разработки: Angular CLI позволяет запускать локальный сервер разработки с помощью команды ng serve. Это позволяет разработчикам видеть изменения в реальном времени при разработке приложения и автоматически перезагружать страницу при внесении изменений в код.
+ Сборка и оптимизация проекта: Angular CLI предоставляет команды для сборки и оптимизации проекта перед его развертыванием. Например, команда ng build собирает проект в определенную директорию, готовую для развертывания на сервере.
+ Тестирование приложения: Angular CLI предоставляет инструменты для запуска и выполнения тестов в Angular-приложении. Это позволяет разработчикам автоматизировать тестирование и обнаруживать потенциальные проблемы и ошибки в приложении.
+ Интеграция с другими инструментами: Angular CLI интегрируется с другими инструментами разработки, такими как Angular DevTools, которые предоставляют дополнительные возможности для отладки и анализа Angular-приложений.
Пример использования Angular CLI:
```javascript
// my-component.component.ts
@Component({ /* .. */ })
export class MyComponent {
constructor(private rest: RestService) {}
// Примеры работы с Observable
public getFields() {
this.rest.getByObservable('http://anyurl.com').subscribe(value => {
// Обработка значения
}, error => {
// Обработка ошибки
});
}
// Примеры работы с Promise
public async getAsyncField() {
try {
const value = await this.rest.getByPromise('http://anyurl.com');
// Обработка значения
} catch (error) {
// Обработка ошибки
}
}
}
```
Вот некоторые команды Angular CLI, которые могут быть полезны при разработке Angular-приложений:
+ `ng new <project-name>`: создает новый проект Angular.
+ `ng generate component <component-name`>: генерирует новый компонент.
+ `ng serve`: запускает локальный сервер разработки.
+ `ng build`: собирает проект для развертывания.
+ `ng test`: запускает тесты в приложении.
## 16. `Что такое схема?`
Angular schematics - это инструмент, который используется в Angular CLI для создания и применения трансформаций к проектам веб-приложений на Angular. С помощью схематиков можно модифицировать существующие схематики и создавать новые, чтобы, например, обновлять код или добавлять новый функционал в проекты.
Angular схематики представляют собой набор правил и шаблонов, которые определяют, какой код должен быть сгенерирован или изменен в проекте. Они могут использоваться для создания различных элементов, таких как компоненты, директивы, модули, сервисы и другие.
Например, с помощью схематиков можно создать новый компонент в проекте Angular CLI с помощью команды ng generate component. Это приведет к созданию соответствующих файлов компонента, включая шаблон, стили и код компонента.
Схематики Angular также позволяют создавать собственные схематики, чтобы автоматизировать и упростить разработку проектов Angular. Вы можете создавать собственные правила и шаблоны, чтобы генерировать код, обновлять существующий код или выполнять другие операции в проекте.
Примеры схематиков Angular:
+ app-shell: генерирует оболочку приложения для запуска серверной версии приложения.
+ component: создает новый компонент.
+ directive: создает новую директиву.
+ module: создает новый модуль NgModule.
Схематики Angular предоставляют мощный инструмент для автоматизации разработки проектов на Angular и упрощения процесса создания и изменения кода. Они помогают разработчикам сэкономить время и уменьшить вероятность ошибок при создании и обновлении кода.
## 17. `Что такое HttpClient и каковы его преимущества?`
HttpClient - это модуль в Angular, который предоставляет возможность выполнять HTTP-запросы к серверу. Он является частью пакета @angular/common/http и предоставляет удобный интерфейс для работы с HTTP-протоколом.
Преимущества HttpClient в Angular включают:
+ Удобство использования: HttpClient предоставляет простой и интуитивно понятный API для выполнения HTTP-запросов. Он предоставляет методы для отправки GET, POST, PUT, DELETE и других типов запросов.
+ Обработка ошибок: HttpClient предоставляет механизмы для обработки ошибок при выполнении HTTP-запросов. Он автоматически обрабатывает ошибки сети, такие как отсутствие соединения или недоступность сервера, и предоставляет возможность обрабатывать ошибки, возвращаемые сервером.
+ Поддержка интерсепторов: HttpClient поддерживает использование интерсепторов, которые позволяют изменять и расширять запросы и ответы. Интерсепторы могут использоваться для добавления заголовков, обработки аутентификации, кэширования и других задач.
+ Поддержка асинхронности: HttpClient предоставляет возможность выполнения асинхронных HTTP-запросов. Он возвращает объект Observable, который позволяет подписываться на результаты запроса и получать их асинхронно.
+ Поддержка типизации: HttpClient поддерживает типизацию данных, возвращаемых сервером. Он позволяет указывать ожидаемый тип данных и автоматически преобразовывать ответ сервера в указанный тип.
## 18. `Что такое многоадресная рассылка в Angular?`
Многоадресная рассылка в Angular - это механизм, который позволяет отправлять данные одновременно нескольким получателям. В Angular многоадресная рассылка обычно используется с помощью объекта Observable из библиотеки RxJS. Observable представляет собой источник данных, который может быть подписан на несколько наблюдателей, чтобы они получали обновления данных одновременно.
Пример использования многоадресной рассылки в Angular:
```javascript
import { Observable } from 'rxjs';
// Создание Observable
const observable = new Observable((observer) => {
// Генерация данных
observer.next('Первое сообщение');
observer.next('Второе сообщение');
observer.next('Третье сообщение');
});
// Подписка на Observable
observable.subscribe((data) => {
console.log(data);
});
```
В этом примере создается Observable, который генерирует три сообщения. Затем мы подписываемся на этот Observable и выводим полученные сообщения в консоль. Каждый подписчик на Observable будет получать все сообщения одновременно.
## 19. `Что такое директива в Angular?`
Директива в Angular - это специальная конструкция, которая позволяет расширять функциональность HTML элементов или создавать собственные элементы с определенным поведением. Директивы позволяют добавлять новые атрибуты, классы или стили к элементам, а также реагировать на события и изменять их внешний вид или поведение.
Директивы в Angular могут быть двух типов: структурные и атрибутные.
Структурные директивы изменяют структуру DOM-дерева, добавляя или удаляя элементы из разметки. Примеры структурных директив в Angular: ngIf, ngFor, ngSwitch.
Атрибутные директивы изменяют внешний вид или поведение элемента, к которому они применяются. Примеры атрибутных директив в Angular: ngStyle, ngClass, ngModel.
Директивы в Angular объявляются с помощью декоратора @Directive и могут содержать различные хуки жизненного цикла, которые позволяют выполнять определенные действия при создании, изменении или удалении директивы.
Например, вот пример директивы в Angular:
```javascript
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[myDirective]'
})
export class MyDirective {
constructor(private elementRef: ElementRef) {
// Используем ElementRef для доступа к элементу, к которому применяется директива
this.elementRef.nativeElement.style.backgroundColor = 'red';
}
}
```
В этом примере директива MyDirective применяется к элементу с атрибутом myDirective и устанавливает красный фон для этого элемента.
## 23. `Как обмениваться данными между компонентами в Angular?`
## 24. `Что такое складывание?`
## 25. `Что такое NoopZone?`
## 26. `Что такое макросы?`
## 27. `Какова цель общего модуля в Angular?`
## 28. `Какие типы компиляторов используются в Angular?`
## 29. `Какова поддержка Angular Elements в браузере?`
## 30. `Какова роль SPA в Angular?`
## 31. `Что произойдет, если вы не предоставите обработчик для наблюдателя?`
## 32. `Что вы подразумеваете под интерполяцией строк?`
## 33. `Что вы подразумеваете под привязкой данных?`
## 34. `Что такое проекция контента?`
## 35. `Что такое шаблонные выражения?`
## 35. `Что такое двусторонняя привязка данных в Angular?`
## 36. `Что такое декораторы и их типы в Angular?`
## 43. `Что такое обнаружение изменений и как работает механизм обнаружения изменений?`
## 44. `Что происходит, когда вы используете тег скрипта в шаблоне?`
## 45. `Когда использовать директиву?`
## 46. `Что такое интерполяция?`
## 47. `В чем разница между чистой и нечистой трубой?`
## 48. `Что такое наблюдаемые?`
## 49. `Что такое пользовательские элементы?`
## 50. `Каковы различные виды директив?`
## 51. `Всегда ли нам нужен модуль маршрутизации?`
## 52. `Что такое (JIT)?`
## 53. `Какова цель файлов метаданных JSON?`
## 54. `Как вы описываете различные зависимости в приложениях Angular?`
## 55. `Что такое декораторы классов в Angular?`
## 56. `Что произойдет, если я импортирую один и тот же модуль дважды?`
## 57. `Каковы способы запуска обнаружения изменений в Angular?`
## 58. `Каковы принципы безопасности в angular?`
## 59. `Каковы принципы безопасности в angular?`
## 60. `Что такое интерфейс командной строки Schematics?`
## 70. `В чем разница между ViewEncapsulation и Shadow DOM в Angular?`
## 71. `Что такое защита маршрута в Angular?`
## 72. `Что такое угловой материал?`
## 73. `Какова цель декоратора NgModule в Angular?`
## 74. `Что такое внедрение зависимостей в Angular?`
## 75. `В чем разница между HttpClient и Http в Angular?`
## 76. `В чем разница между HttpClient и Http в Angular?`
## 77. `Какова цель элемента ng-container в Angular?`
## 78. `Что такое угловая защита?`
## 79. `В чем разница между асинхронным каналом и методом подписки в Angular?`
## 80. `Как вы обмениваетесь данными между компонентами в Angular?`
## 81. `Что такое преобразователь в Angular?`
## 82. `Что такое провайдер в Angular?`
## 83. `В чем разница между сервисом и компонентом в Angular?`
## 84. `В чем разница между ElementRef и Renderer2 в Angular?`
## 85. `В чем разница между формой, управляемой шаблоном, и реактивной формой в Angular?`
## 86. `Что такое сервисный работник Angular?`
## 87. `В чем разница между шаблоном и представлением в Angular?`
## 88. `Что такое механизм обнаружения изменений Angular?`
## 89. `В чем разница между сервисом и компонентом в Angular?`
## 90. `Что такое ссылочная переменная шаблона Angular?`
## 91. `Что такое декоратор ViewChild в Angular?`
## 92. `В чем разница между формой, управляемой шаблоном, и реактивной формой в Angular?`
## 93. `Что такое модуль Angular?`
## 94. `Что такое NgZone в Angular?`
## 95. `В чем разница между ngOnInit и ngAfterViewInit в Angular?`
## 96. `Какова цель декоратора HostListener в Angular?`
## 97. `Какова цель директивы ng-template в Angular?`
## 98. `Какова цель службы ActivatedRoute в Angular?`
## 99. `Какова цель синтаксиса async/await в Angular?`
## 100. `Какова цель директивы ngClass в Angular?`

@ -0,0 +1,593 @@
# Cобеседование Apache Kafka. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# Apache Kafka
- [Cобеседование по Apache Kafka. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Базы данных](#базы-данных)
- [Что такое _«база данных»_?](#что-такое-база-данных)
- [Что такое _«система управления базами данных»_?](#что-такое-система-управления-базами-данных)
[1. Что такое Apache Kafka?] (#1. Что такое Apache Kafka?)
[2. Каковы основные компоненты Kafka?] (#2. Каковы основные компоненты Kafka?)
[3. Что такое Kafka Broker?] (#3. Что такое Kafka Broker?)
[4. Что такое Topic в Kafka?] (#4. Что такое Topic в Kafka?)
[5. Как работает модель публикации/подписки в Kafka?] (#5. Как работает модель публикации/подписки в Kafka?)
[6. Что такое Partition в Kafka и зачем он нужен?] (#6. Что такое Partition в Kafka и зачем он нужен?)
[7. Как Kafka обеспечивает высокую доступность и отказоустойчивость?] (#7. Как Kafka обеспечивает высокую доступность и отказоустойчивость?)
[8. Что такое Consumer Group в Kafka?] (#8. Что такое Consumer Group в Kafka?)
[9. Как происходит балансировка нагрузки между потребителями в группе?] (#9. Как происходит балансировка нагрузки между потребителями в группе?)
[10. Что такое Offset в Kafka?] (#10. Что такое Offset в Kafka?)
[11. Как можно гарантировать порядок сообщений в Kafka?] (#11. Как можно гарантировать порядок сообщений в Kafka?)
[12. Какова роль Zookeeper в Kafka?] (#12. Какова роль Zookeeper в Kafka?)
[13. Что такое Producer в Kafka?] (#13. Что такое Producer в Kafka?)
[14. Как реализовать асинхронную отправку сообщений в Kafka?] (#14. Как реализовать асинхронную отправку сообщений в Kafka?)
[15. Как настроить сериализацию и десериализацию сообщений?] (#15. Как настроить сериализацию и десериализацию сообщений?)
[16. В чем разница между KafkaProducer и KafkaConsumer?] (#16. В чем разница между KafkaProducer и KafkaConsumer?)
[17. Что такое Kafka Streams?] (#17. Что такое Kafka Streams?)
[18. Как использовать Kafka Connect?] (#18. Как использовать Kafka Connect?)
[19. Что такое Retention Policy в Kafka?] (#19. Что такое Retention Policy в Kafka?)
[20. Как можно управлять конфигурацией Kafka?] (#20. Как можно управлять конфигурацией Kafka?)
[21. Что такое Dead Letter Queue (DLQ)
в Kafka?] (#21. Что такое Dead Letter Queue (DLQ)
в Kafka?)
[22. Как реализовать транзакции в Kafka?] (#22. Как реализовать транзакции в Kafka?)
[23. Как производители и потребители обрабатывают ошибки в Kafka?] (#23. Как производители и потребители обрабатывают ошибки в Kafka?)
[24. Каковы основные преимущества использования Kafka?] (#24. Каковы основные преимущества использования Kafka?)
[25. Что такое Kafka Schema Registry?] (#25. Что такое Kafka Schema Registry?)
[26. Как использовать Avro с Kafka?] (#26. Как использовать Avro с Kafka?)
[27. Как обеспечить безопасность в Kafka?] (#27. Как обеспечить безопасность в Kafka?)
[28. Что такое логическая архитектура Kafka?] (#28. Что такое логическая архитектура Kafka?)
[29. Как сделать мониторинг Kafka?] (#29. Как сделать мониторинг Kafka?)
[30. Что такое KSQL?] (#30. Что такое KSQL?)
[31. Как обрабатывать события в реальном времени с помощью Kafka?] (#31. Как обрабатывать события в реальном времени с помощью Kafka?)
[32. Что такое Compaction в Kafka?] (#32. Что такое Compaction в Kafka?)
[33. Как настроить репликацию в Kafka?] (#33. Как настроить репликацию в Kafka?)
[34. Чем отличается acks=all от acks=1?] (#34. Чем отличается acks=all от acks=1?)
[35. Как управлять производительностью Kafka?] (#35. Как управлять производительностью Kafka?)
[36. Что такое Kafka Consumer Lag?] (#36. Что такое Kafka Consumer Lag?)
[37. Как можно отладить Kafka-приложение?] (#37. Как можно отладить Kafka-приложение?)
[38. Что такое Kafka Streams API?] (#38. Что такое Kafka Streams API?)
[39. Как использовать Kafka с Spring Boot?] (#39. Как использовать Kafka с Spring Boot?)
[40. Как реализовать интеграцию Kafka с базой данных?] (#40. Как реализовать интеграцию Kafka с базой данных?)
[41. Что такое Kafka MirrorMaker?] (#41. Что такое Kafka MirrorMaker?)
[42. Как обеспечить обработку событий в порядке их получения?] (#42. Как обеспечить обработку событий в порядке их получения?)
[43. Что такое Kafka REST Proxy?] (#43. Что такое Kafka REST Proxy?)
[44. Как использовать KafkaTemplate в Spring Kafka?] (#44. Как использовать KafkaTemplate в Spring Kafka?)
[45. Как обрабатывать JSON-сообщения в Kafka?] (#45. Как обрабатывать JSON-сообщения в Kafka?)
[46. Что такое Partition Reassignment?] (#46. Что такое Partition Reassignment?)
[47. Как использовать Kafka для микросервисной архитектуры?] (#47. Как использовать Kafka для микросервисной архитектуры?)
[48. Что такое Producer Callback и как его использовать?] (#48. Что такое Producer Callback и как его использовать?)
[49. Как реализовать шифрование сообщений в Kafka?] (#49. Как реализовать шифрование сообщений в Kafka?)
[50. Какие инструменты мониторинга совместимы с Kafka?] (#50. Какие инструменты мониторинга совместимы с Kafka?)
- [Источники](#источники)
Что такое очередь сообщений.
Основные концепции очередей
? Kafka vs Rabbit MQ
Основные сущности Kafka
Zookeper. Хранение метаданных кластера
Kafka кластер. Устройство
Партиционирование. Leader партиция.
Репликация
Настройка Kafka кластера для корректной работы партиционирования и репликации
Устройство файлового хранилища Kafka
TTL
Producer
Producer. Из каких шагов состоит инцициализация
Стратегии коммитинга. Гарантия доставки
Сериализация, Десериализация
Стратегии выбора партиции продюссером
Можно ли из топика (распределен по 3 партициям) прочитать сообщения в том же порядке, в котором они были записаны? Почему?
Как сделать так, чтобы все сообщения по одному клиенту попали в одну партицию?
Timestamp
Headers
Batch size. Linger time
Retry
1. Расскажите мне о ситуации, когда Кафка — не лучший вариант.
2. Как бы вы изменили время удержания в Kafka?
3. Объясните максимальный размер сообщения, которое может получить Kafka.
4. Сравните Apache Kafka с другой популярной потоковой платформой.
5. Когда бы вы использовали функцию кластера в Kafka?
Как разбалансировать кластер в Kafka?
6. Что бы вы сделали, если бы при использовании Kafka возникла ошибка?
## 7. Как бы вы получили одно сообщение от Кафки во время производства данных?
#### Получение одного сообщения из Kafka
Чтобы получить одно сообщение из Kafka во время производства данных, вам нужно использовать **Kafka Consumer**. Вот основные шаги, которые помогут вам это сделать:
1. **Создание Consumer**: Сначала необходимо создать экземпляр Kafka Consumer, указав необходимые параметры конфигурации, такие как `bootstrap.servers`, `group.id`, и `key.deserializer`, `value.deserializer`.
2. **Подписка на топик**: После создания Consumer, вы должны подписаться на нужный топик, из которого хотите получать сообщения. Это делается с помощью метода `subscribe()`.
3. **Получение сообщения**: Для получения сообщения используйте метод `poll()`. Этот метод будет блокировать выполнение, пока не получит сообщение. Чтобы получить только одно сообщение, вы можете использовать `poll(Duration.ofMillis(100))` и затем обработать полученное сообщение.
4. **Коммит смещения**: После обработки сообщения, если вы хотите зафиксировать смещение, используйте метод `commitSync()`, чтобы сохранить текущее положение в потоке сообщений.
Вот пример кода на Java:
```java
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
import java.time.Duration;
import java.util.Collections;
import java.util.Properties;
public class KafkaSingleMessageConsumer {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "my-group");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("my-topic"));
// Получение одного сообщения
ConsumerRecord<String, String> record = consumer.poll(Duration.ofMillis(100)).iterator().next();
System.out.println("Получено сообщение: " + record.value());
// Коммит смещения
consumer.commitSync();
consumer.close();
}
}
```
Этот код создаёт Consumer, подписывается на топик и получает одно сообщение. Не забудьте обработать возможные исключения, такие как `NoSuchElementException`, если сообщений нет.
8. Что вы имеете в виду, когда говорите «отказоустойчивость»?
## 9. Как бы вы интегрировали Kafka с другими фреймворками?
1. **Использование Kafka Connect**: Kafka Connect — это инструмент, который позволяет легко интегрировать Kafka с другими системами, такими как базы данных, хранилища данных и другие системы обработки данных. Он поддерживает множество коннекторов, которые могут быть настроены для автоматической передачи данных между Kafka и другими источниками или приемниками данных.
2. **Интеграция с Apache Spark**: Apache Spark может использовать Kafka для обработки потоковых данных. Spark Streaming позволяет обрабатывать данные в реальном времени, получая их из Kafka. Это позволяет создавать мощные приложения для анализа данных, которые могут обрабатывать большие объёмы информации.
3. **Использование с Apache Storm**: Apache Storm также может быть интегрирован с Kafka для обработки потоков данных. Storm позволяет обрабатывать данные в реальном времени и может использовать Kafka как источник данных, что делает его идеальным для приложений, требующих низкой задержки.
4. **Интеграция с REST API**: Kafka может быть использован в сочетании с REST API для передачи данных между различными приложениями. Это позволяет разработчикам создавать приложения, которые могут взаимодействовать с Kafka через стандартные HTTP-запросы.
5. **Подключение к системам мониторинга и аналитики**: Kafka может быть интегрирован с системами мониторинга и аналитики, такими как Elasticsearch и Grafana, для визуализации и анализа потоковых данных в реальном времени.
Эти методы интеграции позволяют использовать возможности Kafka для создания масштабируемых и эффективных систем обработки данных.
1. Что такое Apache Kafka?
Apache Kafka - это распределенная платформа потоковой передачи данных, которая позволяет публиковать и подписываться на потоки записей. Она разработана для обработки данных в реальном времени и обеспечивает высокую пропускную способность, масштабируемость и надежность.
2. Каковы основные компоненты Kafka?
Основные компоненты:
- Брокеры (Brokers)
- Производители (Producers)
- Потребители (Consumers)
- Топики (Topics)
- ZooKeeper
- Партиции (Partitions)
3. Что такое Kafka Broker?
Брокер - это сервер Kafka, который хранит данные и обслуживает запросы клиентов. Кластер Kafka состоит из нескольких брокеров, где каждый имеет уникальный ID.
4. Что такое Topic в Kafka?
Topic - это категория или канал, в который публикуются записи. Топики могут иметь множество производителей и потребителей. Каждый топик разделен на партиции.
5. Как работает модель публикации/подписки в Kafka?
Производители публикуют сообщения в топики, а потребители подписываются на эти топики для получения сообщений. Это обеспечивает слабую связанность между отправителями и получателями.
6. Что такое Partition в Kafka и зачем он нужен?
Партиция - это упорядоченная последовательность сообщений в топике. Партиции позволяют:
- Распределять данные между брокерами
- Обеспечивать параллельную обработку
- Масштабировать производительность
7. Как Kafka обеспечивает высокую доступность и отказоустойчивость?
Через:
- Репликацию данных
- Распределение партиций между брокерами
- Автоматическое восстановление после сбоев
- Выборы лидера партиции
8. Что такое Consumer Group в Kafka?
Consumer Group - это группа потребителей, которые совместно обрабатывают сообщения из топиков. Каждое сообщение доставляется только одному потребителю в группе.
9. Как происходит балансировка нагрузки между потребителями в группе?
Kafka автоматически распределяет партиции между потребителями в группе. При добавлении или удалении потребителя происходит ребалансировка.
10. Что такое Offset в Kafka?
Offset - это уникальный последовательный идентификатор сообщения в партиции. Потребители используют offset для отслеживания прочитанных сообщений.
11. Как можно гарантировать порядок сообщений в Kafka?
Порядок сообщений гарантируется только в пределах одной партиции. Для обеспечения порядка нужно:
- Использовать один и тот же ключ партиции для связанных сообщений
- Настроить параметр max.in.flight.requests.per.connection=1
- Использовать подтверждения (acks=all)
12. Какова роль Zookeeper в Kafka?
ZooKeeper отвечает за:
- Хранение метаданных о кластере
- Выборы контроллера
- Отслеживание состояния брокеров
- Управление квотами и ACL
Примечание: с версии 3.0 Kafka может работать без ZooKeeper (KRaft).
13. Что такое Producer в Kafka?
Producer - это клиент, который публикует сообщения в топики Kafka. Основные характеристики:
- Может отправлять сообщения синхронно или асинхронно
- Поддерживает балансировку нагрузки
- Имеет встроенные механизмы сериализации
14. Как реализовать асинхронную отправку сообщений в Kafka?
Асинхронная отправка реализуется через:
- Использование метода send() с callback
- Настройку параметра batch.size
- Использование producer.flush() при необходимости
15. Как настроить сериализацию и десериализацию сообщений?
Через:
- Реализацию интерфейсов Serializer и Deserializer
- Настройку key.serializer и value.serializer
- Использование встроенных сериализаторов (String, Integer, etc.)
- Применение форматов как Avro, Protobuf или JSON
16. В чем разница между KafkaProducer и KafkaConsumer?
KafkaProducer:
- Отправляет сообщения
- Управляет партиционированием
- Поддерживает асинхронную отправку
KafkaConsumer:
- Читает сообщения
- Управляет смещениями
- Поддерживает групповое потребление
17. Что такое Kafka Streams?
Kafka Streams - это библиотека для потоковой обработки данных, которая позволяет:
- Создавать приложения для обработки потоков
- Выполнять агрегации и соединения
- Обрабатывать события в реальном времени
- Поддерживать состояние приложения
18. Как использовать Kafka Connect?
Kafka Connect - это фреймворк для интеграции данных, который:
- Поддерживает готовые коннекторы
- Позволяет создавать собственные коннекторы
- Обеспечивает масштабируемость
- Поддерживает распределенный и автономный режимы
19. Что такое Retention Policy в Kafka?
Retention Policy определяет:
- Как долго хранятся сообщения
- Максимальный размер данных
- Правила очистки старых данных
- Политику компактификации
20. Как можно управлять конфигурацией Kafka?
Конфигурацией можно управлять через:
- Файлы конфигурации (server.properties)
- Динамические настройки через API
- Переменные окружения
- Инструменты администрирования
21. Что такое Dead Letter Queue (DLQ) в Kafka?
DLQ - это специальный топик для сообщений, которые не удалось обработать. Используется для:
- Сохранения проблемных сообщений
- Анализа ошибок обработки
- Повторной обработки сообщений
- Мониторинга качества данных
22. Как реализовать транзакции в Kafka?
Транзакции в Kafka реализуются через:
- Использование TransactionalId
- Инициализацию транзакционного продюсера
- Методы beginTransaction() и commitTransaction()
- Настройку isolation.level для потребителей
23. Как производители и потребители обрабатывают ошибки в Kafka?
Обработка ошибок включает:
- Retry-механизмы
- Exception handlers
- Dead Letter Queue
- Мониторинг и логирование
- Настройку таймаутов
24. Каковы основные преимущества использования Kafka?
Основные преимущества:
- Высокая производительность
- Масштабируемость
- Отказоустойчивость
- Долговременное хранение
- Гарантированная доставка сообщений
25. Что такое Kafka Schema Registry?
Schema Registry - это сервис для управления схемами данных, который:
- Хранит и версионирует схемы
- Обеспечивает совместимость
- Поддерживает Avro, Protobuf, JSON Schema
- Валидирует сообщения
26. Как использовать Avro с Kafka?
Для использования Avro нужно:
- Определить схему в формате Avro
- Настроить Schema Registry
- Использовать AvroSerializer/AvroDeserializer
- Управлять эволюцией схем
27. Как обеспечить безопасность в Kafka?
Безопасность обеспечивается через:
- SSL/TLS шифрование
- SASL аутентификацию
- ACL авторизацию
- Аудит доступа
- Шифрование данных
28. Что такое логическая архитектура Kafka?
Логическая архитектура включает:
- Топики и партиции
- Реплики и лидеры
- Производители и потребители
- Группы потребителей
- Контроллер брокера
29. Как сделать мониторинг Kafka?
Мониторинг осуществляется через:
- JMX метрики
- Prometheus/Grafana
- Kafka Manager
- Custom метрики
- Логи брокеров
30. Что такое KSQL?
KSQL - это движок потоковых SQL-запросов для Kafka:
- Позволяет писать SQL-подобные запросы
- Поддерживает агрегации и джойны
- Работает в реальном времени
- Интегрируется с существующими потоками
31. Как обрабатывать события в реальном времени с помощью Kafka?
Обработка в реальном времени осуществляется через:
- Kafka Streams API
- KSQL
- Низкие задержки доставки
- Параллельную обработку партиций
- Оптимизацию производительности
32. Что такое Compaction в Kafka?
Compaction - это механизм очистки топиков, который:
- Сохраняет последнее значение для каждого ключа
- Уменьшает размер данных
- Поддерживает изменяемые состояния
- Оптимизирует хранение
33. Как настроить репликацию в Kafka?
Настройка репликации включает:
- Установку фактора репликации
- Выбор лидера партиции
- Настройку ISR (In-Sync Replicas)
- Управление синхронизацией
34. Чем отличается acks=all от acks=1?
acks=all:
- Ждет подтверждения от всех реплик
- Максимальная надежность
- Большая латентность
acks=1:
- Ждет подтверждения только от лидера
- Средняя надежность
- Меньшая латентность
35. Как управлять производительностью Kafka?
Управление производительностью через:
- Настройку параметров брокера
- Оптимизацию партиций
- Конфигурацию продюсеров/потребителей
- Мониторинг метрик
- Балансировку нагрузки
36. Что такое Kafka Consumer Lag?
Consumer Lag - это отставание потребителя:
- Разница между последним опубликованным и прочитанным сообщением
- Индикатор производительности
- Метрика мониторинга
- Показатель здоровья системы
37. Как можно отладить Kafka-приложение?
Отладка включает:
- Анализ логов
- Мониторинг метрик
- Использование инструментов отладки
- Тестирование конфигураций
- Проверку консьюмер-групп
38. Что такое Kafka Streams API?
Kafka Streams API предоставляет:
- DSL для обработки потоков
- Операции над данными
- Управление состоянием
- Масштабируемость
- Отказоустойчивость
39. Как использовать Kafka с Spring Boot?
Интеграция включает:
- Spring Kafka
- Конфигурацию в application.properties
- KafkaTemplate
- @KafkaListener аннотации
- Обработку ошибок
40. Как реализовать интеграцию Kafka с базой данных?
Интеграция через:
- Kafka Connect
- CDC (Change Data Capture)
- Пользовательские коннекторы
- Транзакционную обработку
41. Что такое Kafka MirrorMaker?
Kafka MirrorMaker - это инструмент для репликации данных между кластерами:
- Поддерживает географическую репликацию
- Обеспечивает аварийное восстановление
- Позволяет агрегировать данные
- Поддерживает фильтрацию топиков
42. Как обеспечить обработку событий в порядке их получения?
Для обеспечения порядка нужно:
- Использовать одну партицию для связанных событий
- Настроить правильный ключ партиционирования
- Использовать временные метки
- Контролировать параллелизм обработки
43. Что такое Kafka REST Proxy?
Kafka REST Proxy:
- Предоставляет HTTP API для Kafka
- Позволяет работать с Kafka без клиентских библиотек
- Поддерживает форматы JSON/Binary/Avro
- Обеспечивает доступ через веб-протоколы
44. Как использовать KafkaTemplate в Spring Kafka?
KafkaTemplate используется для:
- Отправки сообщений в топики
- Обработки подтверждений
- Управления транзакциями
- Обработки ошибок отправки
45. Как обрабатывать JSON-сообщения в Kafka?
Обработка JSON включает:
- Использование JsonSerializer/JsonDeserializer
- Маппинг на Java-объекты
- Валидацию схемы
- Обработку ошибок десериализации
46. Что такое Partition Reassignment?
Partition Reassignment позволяет:
- Перераспределять партиции между брокерами
- Балансировать нагрузку
- Обрабатывать отказы брокеров
- Оптимизировать использование ресурсов
47. Как использовать Kafka для микросервисной архитектуры?
Использование в микросервисах:
- Асинхронная коммуникация
- Паттерн Event Sourcing
- CQRS
- Распределенные транзакции
- Обработка отказов
48. Что такое Producer Callback и как его использовать?
Producer Callback:
- Асинхронная обработка результатов отправки
- Обработка ошибок
- Метрики успешности
- Подтверждение доставки
49. Как реализовать шифрование сообщений в Kafka?
Шифрование реализуется через:
- SSL/TLS на транспортном уровне
- Шифрование на уровне сообщений
- Пользовательские сериализаторы
- Управление ключами шифрования
50. Какие инструменты мониторинга совместимы с Kafka?
Инструменты мониторинга:
- Prometheus/Grafana
- Kafka Manager (CMAK)
- JMX-мониторинг
- ELK Stack
- Datadog
[к оглавлению](#Базы-данных)
# Источники
+ [Википедия](https://ru.wikipedia.org/wiki/)
+ [tokarchuk.ru](http://tokarchuk.ru/2012/08/indexes-classification/)
+ [Quizful](http://www.quizful.net/interview/sql/)
[Вопросы для собеседования](README.md)

@ -0,0 +1,970 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# Java 8
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Java 8](#java-8)
- [Какие нововведения, появились в Java 8 и JDK 8?](#какие-нововведения-появились-в-java-8-и-jdk-8)
- [Что такое _«лямбда»_? Какова структура и особенности использования лямбда-выражения?](#что-такое-лямбда-какова-структура-и-особенности-использования-лямбда-выражения)
- [К каким переменным есть доступ у лямбда-выражений?](#к-каким-переменным-есть-доступ-у-лямбда-выражений)
- [Как отсортировать список строк с помощью лямбда-выражения?](#как-отсортировать-список-строк-с-помощью-лямбда-выражения)
- [Что такое «ссылка на метод»?](#что-такое-ссылка-на-метод)
- [Какие виды ссылок на методы вы знаете?](#какие-виды-ссылок-на-методы-вы-знаете)
- [Объясните выражение `System.out::println`.](#объясните-выражение-systemoutprintln)
- [Что такое «функциональные интерфейсы»?](#что-такое-функциональные-интерфейсы)
- [Для чего нужны функциональные интерфейсы `Function<T,R>`, `DoubleFunction<R>`, `IntFunction<R>` и `LongFunction<R>`?](#для-чего-нужны-функциональные-интерфейсы-functiontr-doublefunctionr-intfunctionr-и-longfunctionr)
- [Для чего нужны функциональные интерфейсы `UnaryOperator<T>`, `DoubleUnaryOperator`, `IntUnaryOperator` и `LongUnaryOperator`?](#для-чего-нужны-функциональные-интерфейсы-unaryoperatort-doubleunaryoperator-intunaryoperator-и-longunaryoperator)
- [Для чего нужны функциональные интерфейсы `BinaryOperator<T>`, `DoubleBinaryOperator`, `IntBinaryOperator` и `LongBinaryOperator`?](#для-чего-нужны-функциональные-интерфейсы-binaryoperatort-doublebinaryoperator-intbinaryoperator-и-longbinaryoperator)
- [Для чего нужны функциональные интерфейсы `Predicate<T>`, `DoublePredicate`, `IntPredicate` и `LongPredicate`?](#для-чего-нужны-функциональные-интерфейсы-predicatet-doublepredicate-intpredicate-и-longpredicate)
- [Для чего нужны функциональные интерфейсы `Consumer<T>`, `DoubleConsumer`, `IntConsumer` и `LongConsumer`?](#для-чего-нужны-функциональные-интерфейсы-consumert-doubleconsumer-intconsumer-и-longconsumer)
- [Для чего нужны функциональные интерфейсы `Supplier<T>`, `BooleanSupplier`, `DoubleSupplier`, `IntSupplier` и `LongSupplier`?](#для-чего-нужны-функциональные-интерфейсы-suppliert--booleansupplier-doublesupplier-intsupplier-и-longsupplier)
- [Для чего нужен функциональный интерфейс `BiConsumer<T,U>`?](#для-чего-нужен-функциональный-интерфейс-biconsumertu)
- [Для чего нужен функциональный интерфейс `BiFunction<T,U,R>`?](#для-чего-нужен-функциональный-интерфейс-bifunctiontur)
- [Для чего нужен функциональный интерфейс `BiPredicate<T,U>`?](#для-чего-нужен-функциональный-интерфейс-bipredicatetu)
- [Для чего нужны функциональные интерфейсы вида `_To_Function`?](#для-чего-нужны-функциональные-интерфейсы-вида-_to_function)
- [Для чего нужны функциональные интерфейсы `ToDoubleBiFunction<T,U>`, `ToIntBiFunction<T,U>` и `ToLongBiFunction<T,U>`?](#для-чего-нужны-функциональные-интерфейсы-todoublebifunctiontu-tointbifunctiontu-и-tolongbifunctiontu)
- [Для чего нужны функциональные интерфейсы `ToDoubleFunction<T>`, `ToIntFunction<T>` и `ToLongFunction<T>`?](#для-чего-нужны-функциональные-интерфейсы-todoublefunctiont-tointfunctiont-и-tolongfunctiont)
- [Для чего нужны функциональные интерфейсы `ObjDoubleConsumer<T>`, `ObjIntConsumer<T>` и `ObjLongConsumer<T>`?](#для-чего-нужны-функциональные-интерфейсы-objdoubleconsumert-objintconsumert-и-objlongconsumert)
- [Что такое `StringJoiner`?](#что-такое-stringjoiner)
- [Что такое `default` методы интрефейса?](#что-такое-default-методы-интрефейса)
- [Как вызывать `default` метод интерфейса в реализующем этот интерфейс классе?](#как-вызывать-default-метод-интерфейса-в-реализующем-этот-интерфейс-классе)
- [Что такое `static` метод интерфейса?](#что-такое-static-метод-интерфейса)
- [Как вызывать `static` метод интерфейса?](#как-вызывать-static-метод-интерфейса)
- [Что такое `Optional`?](#что-такое-optional)
- [Что такое `Stream`?](#что-такое-stream)
- [Какие существуют способы создания стрима?](#какие-существуют-способы-создания-стрима)
- [В чем разница между `Collection` и `Stream`?](#в-чем-разница-между-collection-и-stream)
- [Для чего нужен метод `collect()` в стримах?](#для-чего-нужен-метод-collect-в-стримах)
- [Для чего в стримах применяются методы `forEach()` и `forEachOrdered()`?](#для-чего-в-стримах-применяются-методы-foreach-и-foreachordered)
- [Для чего в стримах предназначены методы `map()` и `mapToInt()`, `mapToDouble()`, `mapToLong()`?](#для-чего-в-стримах-предназначены-методы-map-и-maptoint-maptodouble-maptolong)
- [Какова цель метода `filter()` в стримах?](#какова-цель-метода-filter-в-стримах)
- [Для чего в стримах предназначен метод `limit()`?](#для-чего-в-стримах-предназначен-метод-limit)
- [Для чего в стримах предназначен метод `sorted()`?](#для-чего-в-стримах-предназначен-метод-sorted)
- [Для чего в стримах предназначены методы `flatMap()`, `flatMapToInt()`, `flatMapToDouble()`, `flatMapToLong()`?](#для-чего-в-стримах-предназначены-методы-flatmap-flatmaptoint-flatmaptodouble-flatmaptolong)
- [Расскажите о параллельной обработке в Java 8.](#расскажите-о-параллельной-обработке-в-java-8)
- [Какие конечные методы работы со стримами вы знаете?](#какие-конечные-методы-работы-со-стримами-вы-знаете)
- [Какие промежуточные методы работы со стримами вы знаете?](#какие-промежуточные-методы-работы-со-стримами-вы-знаете)
- [Как вывести на экран 10 случайных чисел, используя `forEach()`?](#как-вывести-на-экран-10-случайных-чисел-используя-foreach)
- [Как можно вывести на экран уникальные квадраты чисел используя метод `map()`?](#как-можно-вывести-на-экран-уникальные-квадраты-чисел-используя-метод-map)
- [Как вывести на экран количество пустых строк с помощью метода `filter()`?](#как-вывести-на-экран-количество-пустых-строк-с-помощью-метода-filter)
- [Как вывести на экран 10 случайных чисел в порядке возрастания?](#как-вывести-на-экран-10-случайных-чисел-в-порядке-возрастания)
- [Как найти максимальное число в наборе?](#как-найти-максимальное-число-в-наборе)
- [Как найти минимальное число в наборе?](#как-найти-минимальное-число-в-наборе)
- [Как получить сумму всех чисел в наборе?](#как-получить-сумму-всех-чисел-в-наборе)
- [Как получить среднее значение всех чисел?](#как-получить-среднее-значение-всех-чисел)
- [Какие дополнительные методы для работы с ассоциативными массивами (maps) появились в Java 8?](#какие-дополнительные-методы-для-работы-с-ассоциативными-массивами-maps-появились-в-java-8)
- [Что такое `LocalDateTime`?](#что-такое-localdatetime)
- [Что такое `ZonedDateTime`?](#что-такое-zoneddatetime)
- [Как получить текущую дату с использованием Date Time API из Java 8?](#как-получить-текущую-дату-с-использованием-date-time-api-из-java-8)
- [Как добавить 1 неделю, 1 месяц, 1 год, 10 лет к текущей дате с использованием Date Time API?](#как-добавить-1-неделю-1-месяц-1-год-10-лет-к-текущей-дате-с-использованием-date-time-api)
- [Как получить следующий вторник используя Date Time API?](#как-получить-следующий-вторник-используя-date-time-api)
- [Как получить вторую субботу текущего месяца используя Date Time API?](#как-получить-вторую-субботу-текущего-месяца-используя-date-time-api)
- [Как получить текущее время с точностью до миллисекунд используя Date Time API?](#как-получить-текущее-время-с-точностью-до-миллисекунд-используя-date-time-api)
- [Как получить текущее время по местному времени с точностью до миллисекунд используя Date Time API?](#как-получить-текущее-время-по-местному-времени-с-точностью-до-миллисекунд-используя-date-time-api)
- [Как определить повторяемую аннотацию?](#как-определить-повторяемую-аннотацию)
- [Что такое `Nashorn`?](#что-такое-nashorn)
- [Что такое `jjs`?](#что-такое-jjs)
- [Какой класс появился в Java 8 для кодирования/декодирования данных?](#какой-класс-появился-в-java-8-для-кодированиядекодирования-данных)
- [Как создать Base64 кодировщик и декодировщик?](#как-создать-base64-кодировщик-и-декодировщик)
- [Источники](#источники)
## Какие нововведения, появились в Java 8 и JDK 8?
+ Методы интерфейсов по умолчанию;
+ Лямбда-выражения;
+ Функциональные интерфейсы;
+ Ссылки на методы и конструкторы;
+ Повторяемые аннотации;
+ Аннотации на типы данных;
+ Рефлексия для параметров методов;
+ _Stream API_ для работы с коллекциями;
+ Параллельная сортировка массивов;
+ Новое API для работы с датами и временем;
+ Новый движок JavaScript _Nashorn_;
+ Добавлено несколько новых классов для потокобезопасной работы;
+ Добавлен новый API для `Calendar` и `Locale`;
+ Добавлена поддержка _Unicode 6.2.0_;
+ Добавлен стандартный класс для работы с _Base64_;
+ Добавлена поддержка беззнаковой арифметики;
+ Улучшена производительность конструктора `java.lang.String(byte[], *)` и метода `java.lang.String.getBytes()`;
+ Новая реализация `AccessController.doPrivileged`, позволяющая устанавливать подмножество привилегий без необходимости проверки всех остальных уровней доступа;
+ _Password-based_ алгоритмы стали более устойчивыми;
+ Добавлена поддержка _SSL/TLS Server Name Indication (NSI)_ в _JSSE Server_;
+ Улучшено хранилище ключей (KeyStore);
+ Добавлен алгоритм _SHA-224_;
+ Удален мост _JDBC - ODBC_;
+ Удален _PermGen_, изменен способ хранения мета-данных классов;
+ Возможность создания профилей для платформы Java SE, которые включают в себя не всю платформу целиком, а некоторую ее часть;
+ Инструментарий
+ Добавлена утилита `jjs` для использования _JavaScript Nashorn_;
+ Команда `java` может запускать _JavaFX_ приложения;
+ Добавлена утилита `jdeps` для анализа _.class_-файлов.
[к оглавлению](#java-8)
## Что такое _«лямбда»_? Какова структура и особенности использования лямбда-выражения?
__Лямбда__ представляет собой набор инструкций, которые можно выделить в отдельную переменную и затем многократно вызвать в различных местах программы.
Основу лямбда-выражения составляет _лямбда-оператор_, который представляет стрелку `->`. Этот оператор разделяет лямбда-выражение на две части: левая часть содержит список параметров выражения, а правая собственно представляет тело лямбда-выражения, где выполняются все действия.
Лямбда-выражение не выполняется само по себе, а образует реализацию метода, определенного в функциональном интерфейсе. При этом важно, что функциональный интерфейс должен содержать только один единственный метод без реализации.
```java
interface Operationable {
int calculate(int x, int y);
}
public static void main(String[] args) {
Operationable operation = (x, y) -> x + y;
int result = operation.calculate(10, 20);
System.out.println(result); //30
}
```
По факту лямбда-выражения являются в некотором роде сокращенной формой внутренних анонимных классов, которые ранее применялись в Java.
+ _Отложенное выполнение (deferred execution) лямбда-выражения_- определяется один раз в одном месте программы, вызываются при необходимости, любое количество раз и в произвольном месте программы.
+ араметры лямбда-выражения_ должны соответствовать по типу параметрам метода функционального интерфейса:
```java
operation = (int x, int y) -> x + y;
//При написании самого лямбда-выражения тип параметров разрешается не указывать:
(x, y) -> x + y;
//Если метод не принимает никаких параметров, то пишутся пустые скобки, например:
() -> 30 + 20;
//Если метод принимает только один параметр, то скобки можно опустить:
n -> n * n;
```
+ _Конечные лямбда-выражения_ не обязаны возвращать какое-либо значение.
```java
interface Printable {
void print(String s);
}
public static void main(String[] args) {
Printable printer = s -> System.out.println(s);
printer.print("Hello, world");
}
```
+ _Блочные лямбда-выражения_ обрамляются фигурными скобками. В блочных лямбда-выражениях можно использовать внутренние вложенные блоки, циклы, конструкции `if`, `switch`, создавать переменные и т.д. Если блочное лямбда-выражение должно возвращать значение, то явным образом применяется оператор `return`:
```java
Operationable operation = (int x, int y) -> {
if (y == 0) {
return 0;
}
else {
return x / y;
}
};
```
+ ередача лямбда-выражения в качестве параметра метода_:
```java
interface Condition {
boolean isAppropriate(int n);
}
private static int sum(int[] numbers, Condition condition) {
int result = 0;
for (int i : numbers) {
if (condition.isAppropriate(i)) {
result += i;
}
}
return result;
}
public static void main(String[] args) {
System.out.println(sum(new int[] {0, 1, 0, 3, 0, 5, 0, 7, 0, 9}, (n) -> n != 0));
}
```
[к оглавлению](#java-8)
## К каким переменным есть доступ у лямбда-выражений?
Доступ к переменным внешней области действия из лямбда-выражения очень схож к доступу из анонимных объектов. Можно ссылаться на:
+ неизменяемые (_effectively final_ - не обязательно помеченные как `final`) локальные переменные;
+ поля класса;
+ статические переменные.
К методам по умолчанию реализуемого функционального интерфейса обращаться внутри лямбда-выражения запрещено.
[к оглавлению](#java-8)
## Как отсортировать список строк с помощью лямбда-выражения?
```java
public static List<String> sort(List<String> list){
Collections.sort(list, (a, b) -> a.compareTo(b));
return list;
}
```
[к оглавлению](#java-8)
## Что такое «ссылка на метод»?
Если существующий в классе метод уже делает все, что необходимо, то можно воспользоваться механизмом __method reference (ссылка на метод)__ для непосредственной передачи этого метода. Такая ссылка передается в виде:
+ `имя_класса::имя_статическогоетода` для статического метода;
+ `объект_класса::имя_метода` для метода экземпляра;
+ азвание_класса::new` для конструктора.
Результат будет в точности таким же, как в случае определения лямбда-выражения, которое вызывает этот метод.
```java
private interface Measurable {
public int length(String string);
}
public static void main(String[] args) {
Measurable a = String::length;
System.out.println(a.length("abc"));
}
```
Ссылки на методы потенциально более эффективны, чем использование лямбда-выражений. Кроме того, они предоставляют компилятору более качественную информацию о типе и при возможности выбора между использованием ссылки на существующий метод и использованием лямбда-выражения, следует всегда предпочитать использование ссылки на метод.
https://www.examclouds.com/ru/java/java-core-russian/method-references-russian
[к оглавлению](#java-8)
## Какие виды ссылок на методы вы знаете?
+ на статический метод;
+ на метод экземпляра;
+ на конструктор.
[к оглавлению](#java-8)
## Объясните выражение `System.out::println`.
Данное выражение иллюстрирует механизм _instance method reference_: передачи ссылки на метод `println()` статического поля `out` класса `System`.
[к оглавлению](#java-8)
## Что такое «функциональные интерфейсы»?
__Функциональный интерфейс__ - это интерфейс, который определяет только один абстрактный метод.
Чтобы точно определить интерфейс как функциональный, добавлена аннотация `@FunctionalInterface`, работающая по принципу `@Override`. Она обозначит замысел и не даст определить второй абстрактный метод в интерфейсе.
Интерфейс может включать сколько угодно `default` методов и при этом оставаться функциональным, потому что `default` методы - не абстрактные.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `Function<T,R>`, `DoubleFunction<R>`, `IntFunction<R>` и `LongFunction<R>`?
__`Function<T, R>`__ - интерфейс, с помощью которого реализуется функция, получающая на вход экземпляр класса `T` и возвращающая на выходе экземпляр класса `R`.
Методы по умолчанию могут использоваться для построения цепочек вызовов (`compose`, `andThen`).
```java
Function<String, Integer> toInteger = Integer::valueOf;
Function<String, String> backToString = toInteger.andThen(String::valueOf);
backToString.apply("123"); // "123"
```
+ `DoubleFunction<R>` - функция получающая на вход `Double` и возвращающая на выходе экземпляр класса `R`;
+ `IntFunction<R>` - функция получающая на вход `Integer` и возвращающая на выходе экземпляр класса `R`;
+ `LongFunction<R>` - функция получающая на вход `Long` и возвращающая на выходе экземпляр класса `R`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `UnaryOperator<T>`, `DoubleUnaryOperator`, `IntUnaryOperator` и `LongUnaryOperator`?
__`UnaryOperator<T>` (унарный оператор)__ принимает в качестве параметра объект типа `T`, выполняет над ними операции и возвращает результат операций в виде объекта типа `T`:
```java
UnaryOperator<Integer> operator = x -> x * x;
System.out.println(operator.apply(5)); // 25
```
+ `DoubleUnaryOperator` - унарный оператор получающий на вход `Double`;
+ `IntUnaryOperator` - унарный оператор получающий на вход `Integer`;
+ `LongUnaryOperator` - унарный оператор получающий на вход `Long`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `BinaryOperator<T>`, `DoubleBinaryOperator`, `IntBinaryOperator` и `LongBinaryOperator`?
__`BinaryOperator<T>` (бинарный оператор)__ - интерфейс, с помощью которого реализуется функция, получающая на вход два экземпляра класса `T` и возвращающая на выходе экземпляр класса `T`.
```java
BinaryOperator<Integer> operator = (a, b) -> a + b;
System.out.println(operator.apply(1, 2)); // 3
```
+ `DoubleBinaryOperator` - бинарный оператор получающий на вход `Double`;
+ `IntBinaryOperator` - бинарный оператор получающий на вход `Integer`;
+ `LongBinaryOperator` - бинарный оператор получающий на вход `Long`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `Predicate<T>`, `DoublePredicate`, `IntPredicate` и `LongPredicate`?
__`Predicate<T>` (предикат)__ - интерфейс, с помощью которого реализуется функция, получающая на вход экземпляр класса `T` и возвращающая на выходе значение типа `boolean`.
Интерфейс содержит различные методы по умолчанию, позволяющие строить сложные условия (`and`, `or`, `negate`).
```java
Predicate<String> predicate = (s) -> s.length() > 0;
predicate.test("foo"); // true
predicate.negate().test("foo"); // false
```
+ `DoublePredicate` - предикат получающий на вход `Double`;
+ `IntPredicate` - предикат получающий на вход `Integer`;
+ `LongPredicate` - предикат получающий на вход `Long`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `Consumer<T>`, `DoubleConsumer`, `IntConsumer` и `LongConsumer`?
__`Consumer<T>` (потребитель)__ - интерфейс, с помощью которого реализуется функция, которая получает на вход экземпляр класса `T`, производит с ним некоторое действие и ничего не возвращает.
```java
Consumer<String> hello = (name) -> System.out.println("Hello, " + name);
hello.accept("world");
```
+ `DoubleConsumer` - потребитель получающий на вход `Double`;
+ `IntConsumer` - потребитель получающий на вход `Integer`;
+ `LongConsumer` - потребитель получающий на вход `Long`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `Supplier<T>`, `BooleanSupplier`, `DoubleSupplier`, `IntSupplier` и `LongSupplier`?
__`Supplier<T>` (поставщик)__ - интерфейс, с помощью которого реализуется функция, ничего не принимающая на вход, но возвращающая на выход результат класса `T`;
```java
Supplier<LocalDateTime> now = LocalDateTime::now;
now.get();
```
+ `DoubleSupplier` - поставщик возвращающий `Double`;
+ `IntSupplier` - поставщик возвращающий `Integer`;
+ `LongSupplier` - поставщик возвращающий `Long`.
[к оглавлению](#java-8)
## Для чего нужен функциональный интерфейс `BiConsumer<T,U>`?
__`BiConsumer<T,U>`__ представляет собой операцию, которая принимает два аргумента классов `T` и `U` производит с ними некоторое действие и ничего не возвращает.
[к оглавлению](#java-8)
## Для чего нужен функциональный интерфейс `BiFunction<T,U,R>`?
__`BiFunction<T,U,R>`__ представляет собой операцию, которая принимает два аргумента классов `T` и `U` и возвращающая результат класса `R`.
[к оглавлению](#java-8)
## Для чего нужен функциональный интерфейс `BiPredicate<T,U>`?
__`BiPredicate<T,U>`__ представляет собой операцию, которая принимает два аргумента классов `T` и `U` и возвращающая результат типа `boolean`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы вида `_To_Function`?
+ `DoubleToIntFunction` - операция принимающая аргумент класса `Double` и возвращающая результат типа `Integer`;
+ `DoubleToLongFunction` - операция принимающая аргумент класса `Double` и возвращающая результат типа `Long`;
+ `IntToDoubleFunction` - операция принимающая аргумент класса `Integer` и возвращающая результат типа `Double`;
+ `IntToLongFunction` - операция принимающая аргумент класса `Integer` и возвращающая результат типа `Long`;
+ `LongToDoubleFunction` - операция принимающая аргумент класса `Long` и возвращающая результат типа `Double`;
+ `LongToIntFunction` - операция принимающая аргумент класса `Long` и возвращающая результат типа `Integer`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `ToDoubleBiFunction<T,U>`, `ToIntBiFunction<T,U>` и `ToLongBiFunction<T,U>`?
+ `ToDoubleBiFunction<T,U>` - операция принимающая два аргумента классов `T` и `U` и возвращающая результат типа `Double`;
+ `ToLongBiFunction<T,U>` - операция принимающая два аргумента классов `T` и `U` и возвращающая результат типа `Long`;
+ `ToIntBiFunction<T,U>` - операция принимающая два аргумента классов `T` и `U` и возвращающая результат типа `Integer`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `ToDoubleFunction<T>`, `ToIntFunction<T>` и `ToLongFunction<T>`?
+ `ToDoubleFunction<T>` - операция принимающая аргумент класса `T` и возвращающая результат типа `Double`;
+ `ToLongFunction<T>` - операция принимающая аргумент класса `T` и возвращающая результат типа `Long`;
+ `ToIntFunction<T>` - операция принимающая аргумент класса `T` и возвращающая результат типа `Integer`.
[к оглавлению](#java-8)
## Для чего нужны функциональные интерфейсы `ObjDoubleConsumer<T>`, `ObjIntConsumer<T>` и `ObjLongConsumer<T>`?
+ `ObjDoubleConsumer<T>` - операция, которая принимает два аргумента классов `T` и `Double`, производит с ними некоторое действие и ничего не возвращает;
+ `ObjLongConsumer<T>` - операция, которая принимает два аргумента классов `T` и `Long`, производит с ними некоторое действие и ничего не возвращает;
+ `ObjIntConsumer<T>` - операция, которая принимает два аргумента классов `T` и `Integer`, производит с ними некоторое действие и ничего не возвращает.
[к оглавлению](#java-8)
## Что такое `StringJoiner`?
Класс `StringJoiner` используется, чтобы создать последовательность строк, разделенных разделителем с возможностью присоединить к полученной строке префикс и суффикс:
```java
StringJoiner joiner = new StringJoiner(".", "prefix-", "-suffix");
for (String s : "Hello the brave world".split(" ")) {
joiner.add(s);
}
System.out.println(joiner); //prefix-Hello.the.brave.world-suffix
```
[к оглавлению](#java-8)
## Что такое `default` методы интрефейса?
Java 8 позволяет добавлять неабстрактные реализации методов в интерфейс, используя ключевое слово `default`:
```java
interface Example {
int process(int a);
default void show() {
System.out.println("default show()");
}
}
```
+ Если класс реализует интерфейс, он может, но не обязан, реализовать методы по-умолчанию, уже реализованные в интерфейсе. Класс наследует реализацию по умолчанию.
+ Если некий класс реализует несколько интерфейсов, которые имеют одинаковый метод по умолчанию, то класс должен реализовать метод с совпадающей сигнатурой самостоятельно. Ситуация аналогична, если один интерфейс имеет метод по умолчанию, а в другом этот же метод является абстрактным - никакой реализации по умолчанию классом не наследуется.
+ Метод по умолчанию не может переопределить метод класса `java.lang.Object`.
+ Помогают реализовывать интерфейсы без страха нарушить работу других классов.
+ Позволяют избежать создания служебных классов, так как все необходимые методы могут быть представлены в самих интерфейсах.
+ Дают свободу классам выбрать метод, который нужно переопределить.
+ Одной из основных причин внедрения методов по умолчанию является возможность коллекций в Java 8 использовать лямбда-выражения.
[к оглавлению](#java-8)
## Как вызывать `default` метод интерфейса в реализующем этот интерфейс классе?
Используя ключевое слово `super` вместе с именем интерфейса:
```java
interface Paper {
default void show() {
System.out.println("default show()");
}
}
class Licence implements Paper {
public void show() {
Paper.super.show();
}
}
```
[к оглавлению](#java-8)
## Что такое `static` метод интерфейса?
Статические методы интерфейса похожи на методы по умолчанию, за исключением того, что для них отсутствует возможность переопределения в классах, реализующих интерфейс.
+ Статические методы в интерфейсе являются частью интерфейса без возможности использовать их для объектов класса реализации;
+ Методы класса `java.lang.Object` нельзя переопределить как статические;
+ Статические методы в интерфейсе используются для обеспечения вспомогательных методов, например, проверки на null, сортировки коллекций и т.д.
[к оглавлению](#java-8)
## Как вызывать `static` метод интерфейса?
Используя имя интерфейса:
```java
interface Paper {
static void show() {
System.out.println("static show()");
}
}
class Licence {
public void showPaper() {
Paper.show();
}
}
```
[к оглавлению](#java-8)
## Что такое `Optional`?
Опциональное значение `Optional` — это контейнер для объекта, который может содержать или не содержать значение `null`. Такая обёртка является удобным средством предотвращения `NullPointerException`, т.к.
имеет некоторые функции высшего порядка, избавляющие от добавления повторяющихся `if null/notNull` проверок:
```java
Optional<String> optional = Optional.of("hello");
optional.isPresent(); // true
optional.ifPresent(s -> System.out.println(s.length())); // 5
optional.get(); // "hello"
optional.orElse("ops..."); // "hello"
```
[к оглавлению](#java-8)
## Что такое `Stream`?
Интерфейс `java.util.Stream` представляет собой последовательность элементов, над которой можно производить различные операции.
Операции над стримами бывают или _промежуточными (intermediate)_ или онечными (terminal)_. Конечные операции возвращают результат определенного типа, а промежуточные операции возвращают тот же стрим. Таким образом вы можете строить цепочки из несколько операций над одним и тем же стримом.
У стрима может быть сколько угодно вызовов промежуточных операций и последним вызов конечной операции. При этом все промежуточные операции выполняются лениво и пока не будет вызвана конечная операция никаких действий на самом деле не происходит (похоже на создание объекта `Thread` или `Runnable`, без вызова `start()`).
Стримы создаются на основе источников каких-либо, например классов из `java.util.Collection`.
Ассоциативные массивы (maps), например `HashMap`, не поддерживаются.
Операции над стримами могут выполняться как последовательно, так и параллельно.
Потоки не могут быть использованы повторно. Как только была вызвана какая-нибудь конечная операция, поток закрывается.
Кроме универсальных объектных существуют особые виды стримов для работы с примитивными типами данных `int`, `long` и `double`: `IntStream`, `LongStream` и `DoubleStream`. Эти примитивные стримы работают так же, как и обычные объектные, но со следующими отличиями:
+ используют специализированные лямбда-выражения, например `IntFunction` или `IntPredicate` вместо `Function` и `Predicate`;
+ поддерживают дополнительные конечные операции `sum()`, `average()`, `mapToObj()`.
[к оглавлению](#java-8)
## Какие существуют способы создания стрима?
1. Из коллекции:
```java
Stream<String> fromCollection = Arrays.asList("x", "y", "z").stream();
```
2. Из набора значений:
```java
Stream<String> fromValues = Stream.of("x", "y", "z");
```
3. Из массива:
```java
Stream<String> fromArray = Arrays.stream(new String[]{"x", "y", "z"});
```
4. Из файла (каждая строка в файле будет отдельным элементом в стриме):
```java
Stream<String> fromFile = Files.lines(Paths.get("input.txt"));
```
5. Из строки:
```java
IntStream fromString = "0123456789".chars();
```
6. С помощью `Stream.builder()`:
```java
Stream<String> fromBuilder = Stream.builder().add("z").add("y").add("z").build();
```
7. С помощью `Stream.iterate()` (бесконечный):
```java
Stream<Integer> fromIterate = Stream.iterate(1, n -> n + 1);
```
8. С помощью `Stream.generate()` (бесконечный):
```java
Stream<String> fromGenerate = Stream.generate(() -> "0");
```
[к оглавлению](#java-8)
## В чем разница между `Collection` и `Stream`?
Коллекции позволяют работать с элементами по-отдельности, тогда как стримы так делать не позволяют, но вместо этого предоставляют возможность выполнять функции над данными как над одним целым.
Также стоит отметить важность самой концепции сущностей: `Collection` - это прежде всего воплощение _Структуры Данных_. Например `Set` не просто хранит в себе элементы, он реализует идею множества с уникальными элементами,
тогда как `Stream`, это прежде всего абстракция необходимая для реализации онвеера вычислений_, собственно поэтому, результатом работы конвеера являются те или иные _Структуры Данных_ или же результаты проверок/поиска и т.п.
[к оглавлению](#java-8)
## Для чего нужен метод `collect()` в стримах?
Метод `collect()` является конечной операцией, которая используется для представление результата в виде коллекции или какой-либо другой структуры данных.
`collect()` принимает на вход `Collector<Тип_источника, Тип_аккумулятора, Тип_результата>`, который содержит четыре этапа: _supplier_ - инициализация аккумулятора, _accumulator_ - обработка каждого элемента, _combiner_ - соединение двух аккумуляторов при параллельном выполнении, _[finisher]_ - необязательный метод последней обработки аккумулятора. В Java 8 в классе `Collectors` реализовано несколько распространённых коллекторов:
+ `toList()`, `toCollection()`, `toSet()` - представляют стрим в виде списка, коллекции или множества;
+ `toConcurrentMap()`, `toMap()` - позволяют преобразовать стрим в `Map`;
+ `averagingInt()`, `averagingDouble()`, `averagingLong()` - возвращают среднее значение;
+ `summingInt()`, `summingDouble()`, `summingLong()` - возвращает сумму;
+ `summarizingInt()`, `summarizingDouble()`, `summarizingLong()` - возвращают `SummaryStatistics` с разными агрегатными значениями;
+ `partitioningBy()` - разделяет коллекцию на две части по соответствию условию и возвращает их как `Map<Boolean, List>`;
+ `groupingBy()` - разделяет коллекцию на несколько частей и возвращает `Map<N, List<T>>`;
+ `mapping()` - дополнительные преобразования значений для сложных `Collector`-ов.
Так же существует возможность создания собственного коллектора через `Collector.of()`:
```java
Collector<String, List<String>, List<String>> toList = Collector.of(
ArrayList::new,
List::add,
(l1, l2) -> { l1.addAll(l2); return l1; }
);
```
[к оглавлению](#java-8)
## Для чего в стримах применяются методы `forEach()` и `forEachOrdered()`?
+ `forEach()` применяет функцию к каждому объекту стрима, порядок при параллельном выполнении не гарантируется;
+ `forEachOrdered()` применяет функцию к каждому объекту стрима с сохранением порядка элементов.
[к оглавлению](#java-8)
## Для чего в стримах предназначены методы `map()` и `mapToInt()`, `mapToDouble()`, `mapToLong()`?
Метод `map()` является промежуточной операцией, которая заданным образом преобразует каждый элемент стрима.
`mapToInt()`, `mapToDouble()`, `mapToLong()` - аналоги `map()`, возвращающие соответствующий числовой стрим (то есть стрим из числовых примитивов):
```java
Stream
.of("12", "22", "4", "444", "123")
.mapToInt(Integer::parseInt)
.toArray(); //[12, 22, 4, 444, 123]
```
Кроме того, `map()` может принимать в себя функциональный интерфейс Functional.
[к оглавлению](#java-8)
## Какова цель метода `filter()` в стримах?
Метод `filter()` является промежуточной операцией принимающей предикат, который фильтрует все элементы, возвращая только те, что соответствуют условию.
[к оглавлению](#java-8)
## Для чего в стримах предназначен метод `limit()`?
Метод `limit()` является промежуточной операцией, которая позволяет ограничить выборку определенным количеством первых элементов.
[к оглавлению](#java-8)
## Для чего в стримах предназначен метод `sorted()`?
Метод `sorted()` является промежуточной операцией, которая позволяет сортировать значения либо в натуральном порядке, либо задавая `Comparator`.
Порядок элементов в исходной коллекции остается нетронутым - `sorted()` всего лишь создает его отсортированное представление.
[к оглавлению](#java-8)
## Для чего в стримах предназначены методы `flatMap()`, `flatMapToInt()`, `flatMapToDouble()`, `flatMapToLong()`?
Метод `flatMap()` похож на map, но может преобразовывать из нескольких элементов (стримов, массивов, коллекций) один. Например можно преобразовать двумерный массив в одномерный:
```java
int[][] arr = {{1,2}, {5,6}, {3,4}};
Arrays.stream(arr).flatMapToInt(x -> Arrays.stream(x)).forEach(System.out::println);
```
Или из стрима листов получить один стрим:
```java
public static void main(String[] args) {
List<Human> humans = asList(
new Human("Sam", asList("Buddy", "Lucy")),
new Human("Bob", asList("Frankie", "Rosie")),
new Human("Marta", asList("Simba", "Tilly")));
List<String> petNames = humans.stream()
.map(human -> human.getPets()) //преобразовываем Stream<Human> в Stream<List<Pet>>
.flatMap(pets -> pets.stream())//"разворачиваем" Stream<List<Pet>> в Stream<Pet>
.collect(Collectors.toList());
System.out.println(petNames); // output [Buddy, Lucy, Frankie, Rosie, Simba, Tilly]
}
```
Или разбить строку по буквам:
```java
Stream
.of("H e l l o", "w o r l d !")
.flatMap((p) -> Arrays.stream(p.split(" ")))
.toArray(String[]::new);//["H", "e", "l", "l", "o", "w", "o", "r", "l", "d", "!"]
```
`flatMapToInt()`, `flatMapToDouble()`, `flatMapToLong()` - это аналоги `flatMap()`, возвращающие соответствующий числовой стрим.
[к оглавлению](#java-8)
## Расскажите о параллельной обработке в Java 8.
Стримы могут быть последовательными и параллельными. Операции над последовательными стримами выполняются в одном потоке процессора, над параллельными — используя несколько потоков процессора. Параллельные стримы используют общий `ForkJoinPool` доступный через статический `ForkJoinPool.commonPool()` метод. При этом, если окружение не является многоядерным, то поток будет выполняться как последовательный. Фактически применение параллельных стримов сводится к тому, что данные в стримах будут разделены на части, каждая часть обрабатывается на отдельном ядре процессора, и в конце эти части соединяются, и над ними выполняются конечные операции.
Для создания параллельного потока из коллекции можно также использовать метод `parallelStream()` интерфейса `Collection`.
Чтобы сделать обычный последовательный стрим параллельным, надо вызвать у объекта `Stream` метод `parallel()`. Метод `isParallel()` позволяет узнать является ли стрим параллельным.
С помощью, методов `parallel()` и `sequential()` можно определять какие операции могут быть параллельными, а какие только последовательными. Так же из любого последовательного стрима можно сделать параллельный и наоборот:
```java
collection
.stream()
.peek(...) // операция последовательна
.parallel()
.map(...) // операция может выполняться параллельно,
.sequential()
.reduce(...) // операция снова последовательна
```
Как правило, элементы передаются в стрим в том же порядке, в котором они определены в источнике данных. При работе с параллельными стримами система сохраняет порядок следования элементов. Исключение составляет метод `forEach()`, который может выводить элементы в произвольном порядке. И чтобы сохранить порядок следования, необходимо применять метод `forEachOrdered()`.
Критерии, которые могут повлиять на производительность в параллельных стримах:
+ Размер данных - чем больше данных, тем сложнее сначала разделять данные, а потом их соединять.
+ Количество ядер процессора. Теоретически, чем больше ядер в компьютере, тем быстрее программа будет работать. Если на машине одно ядро, нет смысла применять параллельные потоки.
+ Чем проще структура данных, с которой работает поток, тем быстрее будут происходить операции. Например, данные из `ArrayList` легко использовать, так как структура данной коллекции предполагает последовательность несвязанных данных. А вот коллекция типа `LinkedList` - не лучший вариант, так как в последовательном списке все элементы связаны с предыдущими/последующими. И такие данные трудно распараллелить.
+ Над данными примитивных типов операции будут производиться быстрее, чем над объектами классов.
+ Крайне не рекомендуется использовать параллельные стримы для сколько-нибудь долгих операций (например сетевых соединений), так как все параллельные стримы работают c одним `ForkJoinPool`, то такие долгие операции могут остановить работу всех параллельных стримов в JVM из-за отсутствия доступных потоков в пуле, т.е. параллельные стримы стоит использовать лишь для коротких операций, где счет идет на миллисекунды, но не для тех где счет может идти на секунды и минуты;
+ Сохранение порядка в параллельных стримах увеличивает издержки при выполнении и если порядок не важен, то имеется возможность отключить его сохранение и тем самым увеличить производительность, использовав промежуточную операцию `unordered()`:
```java
collection.parallelStream()
.sorted()
.unordered()
.collect(Collectors.toList());
```
[к оглавлению](#java-8)
## Какие конечные методы работы со стримами вы знаете?
+ `findFirst()` возвращает первый элемент;
+ `findAny()` возвращает любой подходящий элемент;
+ `collect()` представление результатов в виде коллекций и других структур данных;
+ `count()` возвращает количество элементов;
+ `anyMatch()` возвращает `true`, если условие выполняется хотя бы для одного элемента;
+ `noneMatch()` возвращает `true`, если условие не выполняется ни для одного элемента;
+ `allMatch()` возвращает `true`, если условие выполняется для всех элементов;
+ `min()` возвращает минимальный элемент, используя в качестве условия `Comparator`;
+ `max()` возвращает максимальный элемент, используя в качестве условия `Comparator`;
+ `forEach()` применяет функцию к каждому объекту (порядок при параллельном выполнении не гарантируется);
+ `forEachOrdered()` применяет функцию к каждому объекту с сохранением порядка элементов;
+ `toArray()` возвращает массив значений;
+ `reduce()`позволяет выполнять агрегатные функции и возвращать один результат.
Для числовых стримов дополнительно доступны:
+ `sum()` возвращает сумму всех чисел;
+ `average()` возвращает среднее арифметическое всех чисел.
[к оглавлению](#java-8)
## Какие промежуточные методы работы со стримами вы знаете?
+ `filter()` отфильтровывает записи, возвращая только записи, соответствующие условию;
+ `skip()` позволяет пропустить определённое количество элементов в начале;
+ `distinct()` возвращает стрим без дубликатов (для метода `equals()`);
+ `map()` преобразует каждый элемент;
+ `peek()` возвращает тот же стрим, применяя к каждому элементу функцию;
+ `limit()` позволяет ограничить выборку определенным количеством первых элементов;
+ `sorted()` позволяет сортировать значения либо в натуральном порядке, либо задавая `Comparator`;
+ `mapToInt()`, `mapToDouble()`, `mapToLong()` - аналоги `map()` возвращающие стрим числовых примитивов;
+ `flatMap()`, `flatMapToInt()`, `flatMapToDouble()`, `flatMapToLong()` - похожи на `map()`, но могут создавать из одного элемента несколько.
Для числовых стримов дополнительно доступен метод `mapToObj()`, который преобразует числовой стрим обратно в объектный.
[к оглавлению](#java-8)
## Как вывести на экран 10 случайных чисел, используя `forEach()`?
```java
(new Random())
.ints()
.limit(10)
.forEach(System.out::println);
```
[к оглавлению](#java-8)
## Как можно вывести на экран уникальные квадраты чисел используя метод `map()`?
```java
Stream
.of(1, 2, 3, 2, 1)
.map(s -> s * s)
.distinct()
.collect(Collectors.toList())
.forEach(System.out::println);
```
[к оглавлению](#java-8)
## Как вывести на экран количество пустых строк с помощью метода `filter()`?
```java
System.out.println(
Stream
.of("Hello", "", ", ", "world", "!")
.filter(String::isEmpty)
.count());
```
[к оглавлению](#java-8)
## Как вывести на экран 10 случайных чисел в порядке возрастания?
```java
(new Random())
.ints()
.limit(10)
.sorted()
.forEach(System.out::println);
```
[к оглавлению](#java-8)
## Как найти максимальное число в наборе?
```java
Stream
.of(5, 3, 4, 55, 2)
.mapToInt(a -> a)
.max()
.getAsInt(); //55
```
[к оглавлению](#java-8)
## Как найти минимальное число в наборе?
```java
Stream
.of(5, 3, 4, 55, 2)
.mapToInt(a -> a)
.min()
.getAsInt(); //2
```
[к оглавлению](#java-8)
## Как получить сумму всех чисел в наборе?
```java
Stream
.of(5, 3, 4, 55, 2)
.mapToInt()
.sum(); //69
```
[к оглавлению](#java-8)
## Как получить среднее значение всех чисел?
```java
Stream
.of(5, 3, 4, 55, 2)
.mapToInt(a -> a)
.average()
.getAsDouble(); //13.8
```
[к оглавлению](#java-8)
## Какие дополнительные методы для работы с ассоциативными массивами (maps) появились в Java 8?
+ `putIfAbsent()` добавляет пару «ключ-значение», только если ключ отсутствовал:
`map.putIfAbsent("a", "Aa");`
+ `forEach()` принимает функцию, которая производит операцию над каждым элементом:
`map.forEach((k, v) -> System.out.println(v));`
+ `compute()` создаёт или обновляет текущее значение на полученное в результате вычисления (возможно использовать ключ и текущее значение):
`map.compute("a", (k, v) -> String.valueOf(k).concat(v)); //["a", "aAa"]`
+ `computeIfPresent()` если ключ существует, обновляет текущее значение на полученное в результате вычисления (возможно использовать ключ и текущее значение):
`map.computeIfPresent("a", (k, v) -> k.concat(v));`
+ `computeIfAbsent()` если ключ отсутствует, создаёт его со значением, которое вычисляется (возможно использовать ключ):
`map.computeIfAbsent("a", k -> "A".concat(k)); //["a","Aa"]`
+ `getOrDefault()` в случае отсутствия ключа, возвращает переданное значение по-умолчанию:
`map.getOrDefault("a", "not found");`
+ `merge()` принимает ключ, значение и функцию, которая объединяет передаваемое и текущее значения. Если под заданным ключем значение отсутствует, то записывает туда передаваемое значение.
`map.merge("a", "z", (value, newValue) -> value.concat(newValue)); //["a","Aaz"]`
[к оглавлению](#java-8)
## Что такое `LocalDateTime`?
`LocalDateTime` объединяет вместе `LocaleDate` и `LocalTime`, содержит дату и время в календарной системе ISO-8601 без привязки к часовому поясу. Время хранится с точностью до наносекунды. Содержит множество удобных методов, таких как plusMinutes, plusHours, isAfter, toSecondOfDay и т.д.
[к оглавлению](#java-8)
## Что такое `ZonedDateTime`?
`java.time.ZonedDateTime` — аналог `java.util.Calendar`, класс с самым полным объемом информации о временном контексте в календарной системе ISO-8601. Включает временную зону, поэтому все операции с временными сдвигами этот класс проводит с её учётом.
[к оглавлению](#java-8)
## Как получить текущую дату с использованием Date Time API из Java 8?
```java
LocalDate.now();
```
[к оглавлению](#java-8)
## Как добавить 1 неделю, 1 месяц, 1 год, 10 лет к текущей дате с использованием Date Time API?
```java
LocalDate.now().plusWeeks(1);
LocalDate.now().plusMonths(1);
LocalDate.now().plusYears(1);
LocalDate.now().plus(1, ChronoUnit.DECADES);
```
[к оглавлению](#java-8)
## Как получить следующий вторник используя Date Time API?
```java
LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.TUESDAY));
```
[к оглавлению](#java-8)
## Как получить вторую субботу текущего месяца используя Date Time API?
```java
LocalDate
.of(LocalDate.now().getYear(), LocalDate.now().getMonth(), 1)
.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY))
.with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
```
[к оглавлению](#java-8)
## Как получить текущее время с точностью до миллисекунд используя Date Time API?
```java
new Date().toInstant();
```
[к оглавлению](#java-8)
## Как получить текущее время по местному времени с точностью до миллисекунд используя Date Time API?
```java
LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault());
```
[к оглавлению](#java-8)
## Как определить повторяемую аннотацию?
Чтобы определить повторяемую аннотацию, необходимо создать аннотацию-контейнер для списка повторяемых аннотаций и обозначить повторяемую мета-аннотацией `@Repeatable`:
```java
@interface Schedulers
{
Scheduler[] value();
}
@Repeatable(Schedulers.class)
@interface Scheduler
{
String birthday() default "Jan 8 1935";
}
```
[к оглавлению](#java-8)
## Что такое `Nashorn`?
__Nashorn__ - это движок JavaScript, разрабатываемый на Java компанией Oracle. Призван дать возможность встраивать код JavaScript в приложения Java. В сравнении с _Rhino_, который поддерживается Mozilla Foundation, Nashorn обеспечивает от 2 до 10 раз более высокую производительность, так как он компилирует код и передает байт-код виртуальной машине Java непосредственно в памяти. Nashorn умеет компилировать код JavaScript и генерировать классы Java, которые загружаются специальным загрузчиком. Так же возможен вызов кода Java прямо из JavaScript.
[к оглавлению](#java-8)
## Что такое `jjs`?
`jjs` это утилита командной строки, которая позволяет исполнять программы на языке JavaScript прямо в консоли.
[к оглавлению](#java-8)
## Какой класс появился в Java 8 для кодирования/декодирования данных?
`Base64` - потокобезопасный класс, который реализует кодировщик и декодировщик данных, используя схему кодирования base64 согласно _RFC 4648_ и _RFC 2045_.
Base64 содержит 6 основных методов:
`getEncoder()`/`getDecoder()` - возвращает кодировщик/декодировщик base64, соответствующий стандарту _RFC 4648_;
`getUrlEncoder()`/`getUrlDecoder()` - возвращает URL-safe кодировщик/декодировщик base64, соответствующий стандарту _RFC 4648_;
`getMimeEncoder()`/`getMimeDecoder()` - возвращает MIME кодировщик/декодировщик, соответствующий стандарту _RFC 2045_.
[к оглавлению](#java-8)
## Как создать Base64 кодировщик и декодировщик?
```java
// Encode
String b64 = Base64.getEncoder().encodeToString("input".getBytes("utf-8")); //aW5wdXQ==
// Decode
new String(Base64.getDecoder().decode("aW5wdXQ=="), "utf-8"); //input
```
[к оглавлению](#java-8)
# Источники
+ [Хабрахабр - Новое в Java 8](https://habrahabr.ru/post/216431/)
+ [Хабрахабр - Шпаргалка Java программиста 4. Java Stream API](https://habrahabr.ru/company/luxoft/blog/270383/)
+ [METANIT.COM](http://metanit.com/java/tutorial/9.1.php)
+ [javadevblog.com](http://javadevblog.com/interfejsy-v-java-8-staticheskie-metody-metody-po-umolchaniyu-funktsional-ny-e-interfejsy.html)
[Вопросы для собеседования](README.md)

@ -0,0 +1,171 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# Основы CSS
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Основы CSS](#основы-css)
- [Что такое _«CSS»_?](#что-такое-css)
- [Как в CSS обозначаются комментарии?](#как-в-css-обозначаются-комментарии)
- [Что такое _«селектор»_?](#что-такое-селектор)
- [Перечислите основные виды селекторов.](#перечислите-основные-виды-селекторов)
- [Что такое псевдокласс?](#что-такое-псевдокласс)
- [Какие существуют селекторы аттрибутов?](#какие-существуют-селекторы-аттрибутов)
- [В чем разница между `#my` и `.my`?](#в-чем-разница-между-my-и-my)
- [В чем разница между `margin` и `padding`?](#в-чем-разница-между-margin-и-padding)
- [В чем заключается разница между значениями `0` и `auto` в свойстве `margin`?](#в-чем-заключается-разница-между-значениями-0-и-auto-в-свойстве-margin)
- [Какое свойство задает цвет фона?](#какое-свойство-задает-цвет-фона)
- [Как убрать подчеркивание для всех ссылок на странице?](#как-убрать-подчеркивание-для-всех-ссылок-на-странице)
- [Для чего используется свойство `clear`?](#для-чего-используется-свойство-clear)
- [Как сделать жирным текст во всех элементах `<p>`?](#как-сделать-жирным-текст-во-всех-элементах-p)
- [Как задать красный цвет для всех элементов, имеющих класс `red`?](#как-задать-красный-цвет-для-всех-элементов-имеющих-класс-red)
- [Источники](#источники)
## Что такое _«CSS»_?
__CSS, Cascading Style Sheets (каскадные таблицы стилей)__ - формальный язык описания внешнего вида документа, написанного с использованием языка разметки, который применяется к элементам web-страницы для управления их видом и положением.
Основной целью разработки CSS являлось разделение описания логической структуры web-страницы, которое производится с помощью HTML или других языков разметки от описания внешнего вида этой web-страницы, которое производится с помощью CSS.
[к оглавлению](#Основы-css)
## Как в CSS обозначаются комментарии?
Чтобы пометить, что текст является комментарием, применяют конструкцию `/* ... */`
[к оглавлению](#Основы-css)
## Что такое селектор»_?
__Селектор__ это правило, на основании которого осуществляется выбор элементов в HTML документе для того, чтобы применить к ним определённые стили.
```css
p {
text-align: center;
font-size: 20px;
}
/* p это селектор, text-align и font-size это свойства, а center и 20px значения. */
```
[к оглавлению](#Основы-css)
## Перечислите основные виды селекторов.
+ __селектор `*`__ - выбор всех элементов;
+ __селектор элемента__ - выбор всех элементов в HTML документе, имеющих указанный тег (например: `div`);
+ __селектор класса__ - выбор всех элементов в HTML документе, имеющих указанный класс (например: `.center`);
+ __селектор идентификатора__ - выбор элемента в HTML документе, имеющего указанный идентификатор (например: `#footer`);
+ __селекторы псевдоклассов__ - выбор всех элементов в HTML документе, имеющих указанный псевдокласс (например: `p:first-of-type`);
+ __селекторы атрибутов__ - выбор элементов в зависимости от указанного атрибута элемента или его значения (например: `[href*="youtube"]`).
[к оглавлению](#Основы-css)
## Что такое псевдокласс?
Псевдокласс определяет динамическое состояние элементов, которое изменяется из-за действий пользователя, или же соответствует текущему положению в дереве документа. В отличие от настоящего класса, в явном виде псеводкласс в HTML не указывается, а в CSS указывается через `:` непосредственно после селектора.
Наиболее известные псевдоклассы:
+ `:link` применяется к непосещенным ссылкам;
+ `:visited` применяется к посещенным ссылкам;
+ `:hover` применяется, когда курсор мыши находится в пределах элемента, но не активирует его;
+ `:active` применяется при активации элемента;
+ `:focus` применяется к элементу при получении им фокуса;
+ `:first-child` применяется к первому дочернему элементу селектора, который расположен в дереве элементов документа.
```css
a.snowman:link {
color: blue;
}
a.snowman:visited {
color: purple;
}
a.snowman:active {
color: red;
}
a.snowman:hover {
text-decoration: none;
color: blue;
background-color: yellow;
}
```
[к оглавлению](#Основы-css)
## Какие существуют селекторы аттрибутов?
+ __`[атрибут]`__ - все элементы, имеющие указанный `атрибут`;
+ __`[атрибут=значение]`__ - все элементы, имеющие `атрибут`, значение которого равно `"значение"`;
+ __`[атрибут^=занчение]`__ - все элементы, имеющие `атрибут`, значение которого начинается с `значение`;
+ __`[атрибут|=значение]`__ - все элементы, имеющие `атрибут`, значение которого равно `значение` или начинается с `значение` следующим образом `значение-*` (`значение` с обязательным дефисом, после которого идёт остальное содержимое значения);
+ __`[атрибут$=значение]`__ - все элементы, имеющие `атрибут`, значение которого заканчивается на `значение`;
+ __`[атрибут*=значение]`__ - все элементы, имеющие `атрибут`, значение которого содержит подстроку `значение`;
+ __`[атрибут~=значение]`__ - все элементы, имеющие `атрибут`, значение которого содержит `значение` как одно из значений через пробел.
[к оглавлению](#Основы-css)
## В чем разница между `#my` и `.my`?
`#my` — селектор идентификатора, а `.my` — селектор класса.
[к оглавлению](#Основы-css)
## В чем разница между `margin` и `padding`?
`margin` — внешний отступ, а `padding` — внутренний отступ.
[к оглавлению](#Основы-css)
## В чем заключается разница между значениями `0` и `auto` в свойстве `margin`?
В вертикальных полях — `auto` всегда означает `0`. В горизонтальных полях — `auto` означает `0` только тогда, когда свойство `width` также `auto`.
[к оглавлению](#Основы-css)
## Какое свойство задает цвет фона?
Цвет фона задает свойство `background-color`.
[к оглавлению](#Основы-css)
## Как убрать подчеркивание для всех ссылок на странице?
```css
a {
text-decoration: none;
}
```
[к оглавлению](#Основы-css)
## Для чего используется свойство `clear`?
`clear` устанавливает, с какой стороны элемента запрещено его обтекание другими элементами.
[к оглавлению](#Основы-css)
## Как сделать жирным текст во всех элементах `<p>`?
```css
p {
font-weight: bold;
}
```
[к оглавлению](#Основы-css)
## Как задать красный цвет для всех элементов, имеющих класс `red`?
```css
.red {
color: red;
}
```
[к оглавлению](#Основы-css)
# Источники
+ [myway-blog.ru](http://myway-blog.ru/interview-frontend-web-programmer/)
+ [htmlbook.ru](http://stepbystep.htmlbook.ru/?id=43)
+ [itchief.ru](https://itchief.ru/lessons/html-and-css/css-selectors)
[Вопросы для собеседования](README.md)

@ -0,0 +1,347 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
Нормализация: https://support.microsoft.com/ru-ru/help/283878/description-of-the-database-normalization-basics
Заметки: https://docs.google.com/document/d/1QXEv9hnVRFHaPlPMF3CEIaxL8dQrWYx4MI5PLLj14Cc/edit
# Базы данных
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Базы данных](#базы-данных)
- [Что такое _«база данных»_?](#что-такое-база-данных)
- [Что такое _«система управления базами данных»_?](#что-такое-система-управления-базами-данных)
- [Что такое _«реляционная модель данных»_?](#что-такое-реляционная-модель-данных)
- [Дайте определение терминам _«простой»_, _«составной» (composite)_, _«потенциальный» (candidate)_, _«альтернативный» (alternate)_, _«естественный»_ и _«сурогатный ключ»_.](#дайте-определение-терминам-простой-составной-composite-потенциальный-candidate-альтернативный-alternate-естественный-и-сурогатный-ключ)
- [Что такое _«первичный ключ» (primary key)_? Каковы критерии его выбора?](#что-такое-первичный-ключ-primary-key-каковы-критерии-его-выбора)
- [Что такое _«внешний ключ» (foreign key)_?](#что-такое-внешний-ключ-foreign-key)
- [Что такое _«нормализация»_?](#что-такое-нормализация)
- [Какие существуют нормальные формы?](#какие-существуют-нормальные-формы)
- [Что такое _«денормализация»_? Для чего она применяется?](#что-такое-денормализация-для-чего-она-применяется)
- [Какие существуют типы связей в базе данных? Приведите примеры.](#какие-существуют-типы-связей-в-базе-данных-приведите-примеры)
- [Что такое _«индексы»_? Для чего их используют? В чём заключаются их преимущества и недостатки?](#что-такое-индексы-для-чего-их-используют-в-чём-заключаются-их-преимущества-и-недостатки)
- [Какие типы индексов существуют?](#какие-типы-индексов-существуют)
- [В чем отличие между кластерными и некластерными индексами?](#в-чем-отличие-между-кластерными-и-некластерными-индексами)
- [Имеет ли смысл индексировать данные, имеющие небольшое количество возможных значений?](#имеет-ли-смысл-индексировать-данные-имеющие-небольшое-количество-возможных-значений)
- [Когда полное сканирование набора данных выгоднее доступа по индексу?](#когда-полное-сканирование-набора-данных-выгоднее-доступа-по-индексу)
- [Что такое _«транзакция»_?](#что-такое-транзакция)
- [Требования к транзакциям.](#требования-к-транзакциям)
- [Какие существуют уровни изолированности транзакций?](#какие-существуют-уровни-изолированности-транзакций)
- [Какие проблемы могут возникать при параллельном доступе с использованием транзакций?](#какие-проблемы-могут-возникать-при-параллельном-доступе-с-использованием-транзакций)
- [Cup теорема](#cup-теорема)
- [Источники](#источники)
## Что такое база данных»_?
__База данных__ — организованный и адаптированный для обработки вычислительной системой набор информации.
[к оглавлению](#Базы-данных)
## Что такое система управления базами данных»_?
__Система управления базами данных (СУБД)__ - набор средств общего или специального назначения, обеспечивающий создание, доступ к материалам и управление базой данных.
Основные функции СУБД:
+ управление данными
+ журнализация изменений данных
+ резервное копирование и восстановление данных;
+ поддержка языка определения данных и манипулирования ими.
[к оглавлению](#Базы-данных)
## Что такое реляционная модель данных»_?
__Реляционная модель данных__ — это логическая модель данных и прикладная теория построения реляционных баз данных. Термин «реляционный» означает, что теория основана на математическом понятии отношение (relation), которая формально определяет свойства различных объектов и их взаимосвязи.
Реляционная модель данных включает в себя следующие компоненты:
+ _Структурный аспект_ — данные представляют собой набор отношений.
+ _Аспект целостности_ — отношения отвечают определенным условиям целостности: уровня домена (типа данных), уровня отношения и уровня базы данных.
+ _Аспект обработки (манипулирования)_ — поддержка операторов манипулирования отношениями (реляционная алгебра, реляционное исчисление).
+ _Нормальная форма_ - свойство отношения в реляционной модели данных, характеризующее его с точки зрения избыточности и определённое как совокупность требований, которым должно удовлетворять отношение.
[к оглавлению](#Базы-данных)
## Дайте определение терминам _«простой»_, составной» (composite)_, _«потенциальный» (candidate)_, альтернативный» (alternate)_, естественный»_ и сурогатный ключ»_.
__Простой ключ__ состоит из одного атрибута (поля). __Составной__ - из двух и более.
__Потенциальный ключ__ - простой или составной ключ, который уникально идентифицирует каждую запись набора данных. При этом потенциальный ключ должен обладать критерием неизбыточности: при удалении любого из полей набор полей перестает уникально идентифицировать запись.
Из множества всех потенциальных ключей набора данных выбирают первичный ключ, все остальные ключи называют __альтернативными__.
__Естественный Ключ__ набор атрибутов описываемой записью сущности, уникально её идентифицирующий (например, номер паспорта для человека)
__Суррогатный Ключ__ автоматически сгенерированное поле, никак не связанное с информационным содержанием записи. Обычно в роли СК выступает автоинкрементное поле типа INTEGER.
[к оглавлению](#Базы-данных)
## Что такое _«первичный ключ» (primary key)_? Каковы критерии его выбора?
__Первичный ключ (primary key)__ уникальный идентификатор записи в табице. В реляционной модели данных один из _потенциальных ключей_ отношения, выбранный в качестве основного ключа (ключа по умолчанию).
Если в отношении имеется единственный потенциальный ключ, он является и первичным ключом. Если потенциальных ключей несколько, один из них выбирается в качестве первичного, а другие называют альтернативными»_.
В качестве первичного обычно выбирается тот из потенциальных ключей, который наиболее удобен. Поэтому в качестве первичного ключа, как правило, выбирают тот, который имеет наименьший размер (физического хранения) и/или включает наименьшее количество атрибутов. Другой критерий выбора первичного ключа — сохранение его уникальности со временем. Поэтому в качестве первичного ключа стараются выбирать такой потенциальный ключ, который с наибольшей вероятностью никогда не утратит уникальность.
[к оглавлению](#Базы-данных)
## Что такое _«внешний ключ» (foreign key)_?
__Внешний ключ (foreign key)__ — подмножество атрибутов некоторого отношения A, значения которых должны совпадать со значениями некоторого потенциального ключа некоторого отношения B.
Внешние ключи позволяют установить связи между таблицами. Внешний ключ устанавливается для столбцов из зависимой, подчиненной таблицы, и указывает на один из столбцов из главной таблицы. Как правило, __внешний ключ указывает на первичный ключ из связанной главной таблицы__
[к оглавлению](#Базы-данных)
## Что такое _«нормализация»_?
_Нормализация_ - процесс замены исходной схемы другой схемой, в которой наборы данных имеют более простую и логичную структуру.
Нормализация предназначена для приведения структуры базы данных к виду, обеспечивающему минимальную логическую избыточность, и не имеет целью уменьшение или увеличение производительности работы или же уменьшение или увеличение физического объёма базы данных. Конечной целью нормализации является уменьшение потенциальной противоречивости хранимой в базе данных информации.
[к оглавлению](#Базы-данных)
## Какие существуют нормальные формы?
__Первая нормальная форма (1NF)__ - Отношение находится в 1NF, если значения всех его атрибутов атомарны (неделимы).
+ В каждой ячейке таблицы должно находиться только 1 значение.
+ Строки не должны повторяться
__Вторая нормальная форма (2NF)__ - Отношение находится в 2NF, если оно находится в 1NF, и при этом все неключевые атрибуты зависят только от ключа целиком, а не от какой-то его части. Чтобы привести таблицу в 2NF необходимо ее декомпозировать на несколько зависящих друг от друга.
+ Таблица в 1NF.
+ Все атрибуты зависят целиком от primary key,а не от его части.
__Третья нормальная форма (3NF)__ - Отношение находится в 3NF, если оно находится в 2NF и все неключевые атрибуты не зависят друг от друга.
+ Таблица в 2NF.
+ Все атрибуты зависят только от primary key, но не от других атрибутов.
__Четвёртая нормальная форма (4NF)__ - Отношение находится в 4NF , если оно находится в 3NF и если в нем не содержатся независимые группы атрибутов, между которыми существует отношение «многие-ко-многим».
+ Таблица в 3NF.
+ Ключевые атрибуты не должны зависеть от неключевых.
__Пятая нормальная форма (5NF)__ - Отношение находится в 5NF, когда каждая нетривиальная зависимость соединения в ней определяется потенциальным ключом (ключами) этого отношения.
__Шестая нормальная форма (6NF)__ - Отношение находится в 6NF, когда она удовлетворяет всем нетривиальным зависимостям соединения, т.е. когда она неприводима, то есть не может быть подвергнута дальнейшей декомпозиции без потерь. Каждая переменная отношения, которая находится в 6NF, также находится и в 5NF. Введена как обобщение пятой нормальной формы для хронологической базы данных.
__Нормальная форма Бойса-Кодда, усиленная 3 нормальная форма (BCNF)__ - Отношение находится в BCNF, когда каждая её нетривиальная и неприводимая слева функциональная зависимость имеет в качестве своего детерминанта некоторый потенциальный ключ.
__Доменно-ключевая нормальная форма (DKNF)__ - Отношение находится в DKNF, когда каждое наложенное на неё ограничение является логическим следствием ограничений доменов и ограничений ключей, наложенных на данное отношение.
[к оглавлению](#Базы-данных)
## Что такое _«денормализация»_? Для чего она применяется?
__Денормализация базы данных__ — это процесс осознанного приведения базы данных к виду, в котором она не будет соответствовать правилам нормализации. Обычно это необходимо для повышения производительности и скорости извлечения данных, за счет увеличения избыточности данных.
[к оглавлению](#Базы-данных)
## Какие существуют типы связей в базе данных? Приведите примеры.
+ __OneToOne ОдинКОдному__ - любому значению атрибута А соответствует только одно значение атрибута В, и наоборот.
>Каждый университет гарантированно имеет 1-го ректора: _1 университет → 1 ректор_.
+ __OneToMany ОдинКоМногим__ - любому значению атрибута А соответствует 0, 1 или несколько значений атрибута В.
>В каждом университете есть несколько факультетов: _1 университет → много факультетов_.
+ __ManyToOne МногиеКОдному__ - связь многие к одному, обратная связь для OneToMany
>Многие университеты находятся в одном городе.
+ __МногиеКоМногим__ - любому значению атрибута А соответствует 0, 1 или несколько значений атрибута В, и любому значению атрибута В соответствует 0, 1 или несколько значение атрибута А.
>1 профессор может преподавать на нескольких факультетах, в то же время на 1-ом факультете может преподавать несколько профессоров: _Несколько профессоров ↔ Несколько факультетов_.
Каждую из которых можно разделить еще на два вида:
+ Bidirectional (пер. - Двунаправленный) - две связи
+ Unidirectional (пер. - Однонаправленный ) — ссылка на связь устанавливается у всех Entity, то есть в случае OneToOne A-B в Entity A есть ссылка на Entity B, в Entity B есть ссылка на Entity A, Entity A считается владельцем этой связи (это важно для случаев каскадного удаления данных, тогда при удалении A также будет удалено B, но не наоборот).Unidirectional - ссылка на связь устанавливается только с одной стороны, то есть в случае OneToOne A-B только у Entity A будет ссылка на Entity B, у Entity B ссылки на A не будет.
[к оглавлению](#Базы-данных)
## Что такое _«индексы»_? Для чего их используют? В чём заключаются их преимущества и недостатки?
__Индекс (index)__ — объект базы данных (отдельная таблица), создаваемый с целью повышения производительности выборки данных. Как закладка у книги.
Наборы данных могут иметь большое количество записей, которые хранятся в произвольном порядке, и их поиск по заданному критерию путём последовательного просмотра набора данных запись за записью может занимать много времени. Индекс формируется из значений одного или нескольких полей и указателей на соответствующие записи набора данных, - таким образом, достигается значительный прирост скорости выборки из этих данных.
```java
CREATE INDEX имя_индекса ON имя_таблицы;
```
Преимущества
+ ускорение поиска и сортировки по определенному полю или набору полей.
+ обеспечение уникальности данных.
Недостатки
+ требование дополнительного места на диске и в оперативной памяти и чем больше/длиннее ключ, тем больше размер индекса.
+ замедление операций вставки, обновления и удаления записей, поскольку при этом приходится обновлять сами индексы.
Индексы предпочтительней для:
+ Поля-счетчика, чтобы в том числе избежать и повторения значений в этом поле;
+ Поля, по которому проводится сортировка данных;
+ Полей, по которым часто проводится соединение наборов данных. Поскольку в этом случае данные располагаются в порядке возрастания индекса и соединение происходит значительно быстрее;
+ Поля, которое объявлено первичным ключом (primary key);
+ Поля, в котором данные выбираются из некоторого диапазона. В этом случае как только будет найдена первая запись с нужным значением, все последующие значения будут расположены рядом.
Использование индексов нецелесообразно для:
+ Полей, которые редко используются в запросах;
+ Полей, которые содержат всего два или три значения, например: ужской_, енский пол_ или значения _«да»_, _«нет»_.
[к оглавлению](#Базы-данных)
## Какие типы индексов существуют?
__По порядку сортировки__
+ _упорядоченные_ — индексы, в которых элементы упорядочены;
+ озрастающие_;
+ _убывающие_;
+ еупорядоченные_ — индексы, в которых элементы неупорядочены.
__По источнику данных__
+ _индексы по представлению (view)_;
+ _индексы по выражениям_.
__По воздействию на источник данных__
+ _кластерный индекс_ - при определении в наборе данных физическое расположение данных перестраивается в соответствии со структурой индекса. Логическая структура набора данных в этом случае представляет собой скорее словарь, чем индекс. Данные в словаре физически упорядочены, например по алфавиту. Кластерные индексы могут дать существенное увеличение производительности поиска данных даже по сравнению с обычными индексами. Увеличение производительности особенно заметно при работе с последовательными данными.
+ екластерный индекс_ — наиболее типичные представители семейства индексов. В отличие от кластерных, они не перестраивают физическую структуру набора данных, а лишь организуют ссылки на соответствующие записи. Для идентификации нужной записи в наборе данных некластерный индекс организует специальные указатели, включающие в себя: информацию об идентификационном номере файла, в котором хранится запись; идентификационный номер страницы соответствующих данных; номер искомой записи на соответствующей странице; содержимое столбца.
__По структуре__
+ _B*-деревья_;
+ _B+-деревья_;
+ _B-деревья_;
+ _Хэши_.
__По количественному составу__
+ _простой индекс (индекс с одним ключом)_ — строится по одному полю;
+ _составной (многоключевой, композитный) индекс_ — строится по нескольким полям при этом важен порядок их следования;
+ _индекс с включенными столбцами_ — некластеризованный индекс, дополнительно содержащий кроме ключевых столбцов еще и неключевые;
+ _главный индекс (индекс по первичному ключу)_ — это тот индексный ключ, под управлением которого в данный момент находится набор данных. Набор данных не может быть отсортирован по нескольким индексным ключам одновременно. Хотя, если один и тот же набор данных открыт одновременно в нескольких рабочих областях, то у каждой копии набора данных может быть назначен свой главный индекс.
__По характеристике содержимого__
+ _уникальный индекс_ состоит из множества уникальных значений поля;
+ _плотный индекс_ (NoSQL) — индекс, при котором, каждом документе в индексируемой коллекции соответствует запись в индексе, даже если в документе нет индексируемого поля.
+ _разреженный индекс_ (NoSQL) — тот, в котором представлены только те документы, для которых индексируемый ключ имеет какое-то определённое значение (существует).
+ _пространственный индекс_ — оптимизирован для описания географического местоположения. Представляет из себя многоключевой индекс состоящий из широты и долготы.
+ _составной пространственный индекс_ — индекс, включающий в себя кроме широты и долготы ещё какие-либо мета-данные (например теги). Но географические координаты должны стоять на первом месте.
+ _полнотекстовый (инвертированный) индекс_ — словарь, в котором перечислены все слова и указано, в каких местах они встречаются. При наличии такого индекса достаточно осуществить поиск нужных слов в нём и тогда сразу же будет получен список документов, в которых они встречаются.
+ _хэш-индекс_ предполагает хранение не самих значений, а их хэшей, благодаря чему уменьшается размер (а, соответственно, и увеличивается скорость их обработки) индексов из больших полей. Таким образом, при запросах с использованием хэш-индексов, сравниваться будут не искомое со значения поля, а хэш от искомого значения с хэшами полей.
Из-за нелинейнойсти хэш-функций данный индекс нельзя сортировать по значению, что приводит к невозможности использования в сравнениях больше/меньше и «is null». Кроме того, так как хэши не уникальны, то для совпадающих хэшей применяются методы разрешения коллизий.
+ _битовый индекс (bitmap index)_ — метод битовых индексов заключается в создании отдельных битовых карт (последовательностей 0 и 1) для каждого возможного значения столбца, где каждому биту соответствует запись с индексируемым значением, а его значение равное 1 означает, что запись, соответствующая позиции бита содержит индексируемое значение для данного столбца или свойства.
+ _обратный индекс (reverse index)_ — B-tree индекс, но с реверсированным ключом, используемый в основном для монотонно возрастающих значений (например, автоинкрементный идентификатор) в OLTP системах с целью снятия конкуренции за последний листовой блок индекса, т.к. благодаря переворачиванию значения две соседние записи индекса попадают в разные блоки индекса. Он не может использоваться для диапазонного поиска.
+ ункциональный индекс, индекс по вычисляемому полю (function-based index)_ — индекс, ключи которого хранят результат пользовательских функций. Функциональные индексы часто строятся для полей, значения которых проходят предварительную обработку перед сравнением в команде SQL. Например, при сравнении строковых данных без учета регистра символов часто используется функция UPPER. Кроме того, функциональный индекс может помочь реализовать любой другой отсутствующий тип индексов данной СУБД.
+ _первичный индекс_ — уникальный индекс по полю первичного ключа.
+ _вторичный индекс_ — индекс по другим полям (кроме поля первичного ключа).
+ _XML-индекс_ — вырезанное материализованное представление больших двоичных XML-объектов (BLOB) в столбце с типом данных xml.
__По механизму обновления__
+ _полностью перестраиваемый_ — при добавлении элемента заново перестраивается весь индекс.
+ _пополняемый (балансируемый)_ — при добавлении элементов индекс перестраивается частично (например одна из ветви) и периодически балансируется.
__По покрытию индексируемого содержимого__
+ _полностью покрывающий (полный) индекс_ — покрывает всё содержимое индексируемого объекта.
+ астичный индекс (partial index)_ — это индекс, построенный на части набора данных, удовлетворяющей определенному условию самого индекса. Данный индекс создан для уменьшения размера индекса.
+ _инкрементный (delta) индекс_ — индексируется малая часть данных(дельта), как правило, по истечении определённого времени. Используется при интенсивной записи. Например, полный индекс перестраивается раз в сутки, а дельта-индекс строится каждый час. По сути это частичный индекс по временной метке.
+ _индекс реального времени (real-time index)_ — особый вид инкрементного индекса, характеризующийся высокой скоростью построения. Предназначен для часто меняющихся данных.
__Индексы в кластерных системах__
+ _глобальный индекс_ — индекс по всему содержимому всех сегментов БД (shard).
+ _сегментный индекс_ — глобальный индекс по полю-сегментируемому ключу (shard key). Используется для быстрого определения сегмента, на котором хранятся данные в процессе маршрутизации запроса в кластере БД.
+ окальный индекс_ — индекс по содержимому только одного сегмента БД.
[к оглавлению](#Базы-данных)
## В чем отличие между кластерными и некластерными индексами?
Некластерные индексы - данные физически расположены в произвольном порядке, но логически упорядочены согласно индексу. Такой тип индексов подходит для часто изменяемого набора данных.
При кластерном индексировании данные физически упорядочены, что серьезно повышает скорость выборок данных (но только в случае последовательного доступа к данным). Для одного набора данных может быть создан только один кластерный индекс.
[к оглавлению](#Базы-данных)
## Имеет ли смысл индексировать данные, имеющие небольшое количество возможных значений?
Примерное правило, которым можно руководствоваться при создании индекса - если объем информации (в байтах) НЕ удовлетворяющей условию выборки меньше, чем размер индекса (в байтах) по данному условию выборки, то в общем случае оптимизация приведет к замедлению выборки.
[к оглавлению](#Базы-данных)
## Когда полное сканирование набора данных выгоднее доступа по индексу?
Полное сканирование производится многоблочным чтением. Сканирование по индексу - одноблочным. Также, при доступе по индексу сначала идет сканирование самого индекса, а затем чтение блоков из набора данных. Число блоков, которые надо при этом прочитать из набора зависит от фактора кластеризации. Если суммарная стоимость всех необходимых одноблочных чтений больше стоимости полного сканирования многоблочным чтением, то полное сканирование выгоднее и оно выбирается оптимизатором.
Таким образом, полное сканирование выбирается при слабой селективности предикатов зароса и/или слабой кластеризации данных, либо в случае очень маленьких наборов данных.
[к оглавлению](#Базы-данных)
## Что такое _«транзакция»_?
__Транзакция__ - это воздействие на базу данных, переводящее её из одного целостного состояния в другое и выражаемое в изменении данных, хранящихся в базе данных.
[к оглавлению](#Базы-данных)
## Требования к транзакциям.
Требования, для наиболее эфективной и безопасной работы транзакций.
__Атомарность (atomicity)__ гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной.
__Согласованность (consistency)__ требование, подразумевающее, что в результате работы транзакции данные будут допустимыми. Это вопрос не технологии, а бизнес-логики: например, если количество денег на счете не может быть отрицательным, логика транзакции должна проверять, не выйдет ли в результате отрицательных значений.
__Изолированность (isolation)__. Во время выполнения транзакции параллельные транзакции не должны оказывать влияние на её результат.
__Долговечность (durability)__. Независимо от проблем на нижних уровнях изменения, сделанные успешно завершённой транзакцией, должны остаться сохранёнными после возвращения системы в работу. Другими словами, если пользователь получил подтверждение от системы, что транзакция выполнена, он может быть уверен, что сделанные им изменения не будут отменены из-за какого-либо сбоя.
[к оглавлению](#Базы-данных)
## Какие существуют уровни изолированности транзакций?
В порядке увеличения изолированности транзакций и, соответственно, надёжности работы с данными:
+ __Чтение незавершенных транзакций (read uncommitted)__ — чтение незафиксированных изменений как своей транзакции, так и параллельных транзакций. Если несколько параллельных транзакций пытаются изменять одну и ту же строку таблицы, то в окончательном варианте строка будет иметь значение, определенное всем набором успешно выполненных транзакций. Гарантирует только отсутствие потерянных обновлений.
Типичный способ реализации данного уровня изоляции — блокировка данных на время выполнения команды изменения, что гарантирует, что команды изменения одних и тех же строк, запущенные параллельно, фактически выполнятся последовательно, и ни одно из изменений не потеряется. Транзакции, выполняющие только чтение, при данном уровне изоляции никогда не блокируются.
+ __Чтение завершенных транзакций (read committed)__ — На этом уровне обеспечивается защита от чернового, «грязного» чтения, тем не менее, в процессе работы одной транзакции другая может быть успешно завершена и сделанные ею изменения зафиксированы. В итоге первая транзакция будет работать с другим набором данных. По умолчанию в MySql и PostgreSQL
Работает либо через __Блокирование читаемых и изменяемых данных__, т.е. пишущая транзакция блокирует изменяемые данные для читающих транзакций, работающих на уровне read committed или более высоком, до своего завершения, препятствуя, таким образом, «грязному» чтению, а данные, блокируемые читающей транзакцией, освобождаются сразу после завершения операции SELECT (таким образом, ситуация «неповторяющегося чтения» может возникать на данном уровне изоляции).
Либо __Сохранение нескольких версий параллельно изменяемых строк__, т.е. при каждом изменении строки СУБД создаёт новую версию этой строки, с которой продолжает работать изменившая данные транзакция, в то время как любой другой «читающей» транзакции возвращается последняя зафиксированная версия. Преимущество такого подхода в том, что он обеспечивает бо́льшую скорость, так как предотвращает блокировки. Однако он требует, по сравнению с первым, существенно бо́льшего расхода оперативной памяти, которая тратится на хранение версий строк. Кроме того, при параллельном изменении данных несколькими транзакциями может создаться ситуация, когда несколько параллельных транзакций произведут несогласованные изменения одних и тех же данных (поскольку блокировки отсутствуют, ничто не помешает это сделать). Тогда та транзакция, которая зафиксируется первой, сохранит свои изменения в основной БД, а остальные параллельные транзакции окажется невозможно зафиксировать (так как это приведёт к потере обновления первой транзакции). Единственное, что может в такой ситуации СУБД — это откатить остальные транзакции и выдать сообщение об ошибке «Запись уже изменена».
+ __Повторяемость чтения (repeatable read)__ — Уровень, при котором читающая транзакция «не видит» изменения данных, которые были ею ранее прочитаны. При этом никакая другая транзакция не может изменять данные, читаемые текущей транзакцией, пока та не окончена.
Блокировки в разделяющем режиме применяются ко всем данным, считываемым любой инструкцией транзакции, и сохраняются до её завершения. Это запрещает другим транзакциям изменять строки, которые были считаны незавершённой транзакцией. Однако другие транзакции могут вставлять новые строки, соответствующие условиям поиска инструкций, содержащихся в текущей транзакции. При повторном запуске инструкции текущей транзакцией будут извлечены новые строки, что приведёт к фантомному чтению. Учитывая то, что разделяющие блокировки сохраняются до завершения транзакции, а не снимаются в конце каждой инструкции, степень параллелизма ниже, чем при уровне изоляции READ COMMITTED. Поэтому пользоваться данным и более высокими уровнями транзакций без необходимости обычно не рекомендуется.
+ __Упорядочиваемость (serializable)__ — Самый высокий уровень изолированности; транзакции полностью изолируются друг от друга, каждая выполняется так, как будто параллельных транзакций не существует, а они работают последовательно Только на этом уровне параллельные транзакции не подвержены эффекту «фантомного чтения».
Не все СУБД поддерживают все 4 вышеперечисленных уровня изолированности, а некоторые СУБД вводят дополнительные уровни.
[к оглавлению](#Базы-данных)
## Какие проблемы могут возникать при параллельном доступе с использованием транзакций?
При параллельном выполнении транзакций возможны следующие проблемы:
+ __Потерянное обновление (lost update)__ — когда две транзакции записывают разные значения в одну и ту же ячейку, одно из изменений теряется;
+ __«Грязное» чтение (dirty read)__ — когда читаются данные, которые в этот момент изменяются транзакцией, а потом транзакция откатывается и данные исчезают. В MySQl решается Read Uncommitted, в PostgreSQL - не поддерживается вообще
+ __Неповторяющееся чтение (non-repeatable read)__ — одна транзакция в ходе своего выполнения несколько раз выбирает множество строк по одним и тем же критериям. Другая транзакция в интервалах между этими выборками меняет или удаляет данные, используемых в критериях выборки первой транзакции, и успешно заканчивается. Из-за этого результаты выборки в первой транзакции будут разными.
+ __Фантомное чтение (phantom reads)__ — одна транзакция в ходе своего выполнения несколько раз выбирает множество строк по одним и тем же критериям. Другая транзакция в интервалах между этими выборками добавляет новые данные, используемых в критериях выборки первой транзакции, и успешно заканчивается. От неповторяющегося чтения оно отличается тем, что результат повторного обращения к данным изменился не из-за изменения/удаления самих этих данных, а из-за появления новых (фантомных) данных.
[к оглавлению](#Базы-данных)
## Cup теорема
Она гласит, что в распределенной системе можно обеспечить только два свойства из трех: согласованность, доступность и устойчивость к разделению. Помогает понимать, как конкретная распределенная система будет работать и какую систему базы данных (например Postgresql или MySql) лучше выбрать. Однако многими учёными и практиками теорема CAP критикуется за вольность трактовки и даже недостоверность.
__Согласованность данных (consistency)__
Когда во всех узлах в каждый момент времени данные согласованы друг с другом, то есть не противоречат друг другу. Если в одном из узлов в ячейке базы данных есть данные, такие же данные есть на всех остальных узлах.
__Доступность (availability)__
Когда любой запрос может быть обработан системой, вне зависимости от ее состояния.
__Устойчивость к разделению (partition tolerance)__
Когда расщепление системы на несколько изолированных секций не приводит к некорректному отклику от каждой из секций: отвалилась сеть между двумя узлами, но каждый из них может корректно отвечать своим клиентам.
# Источники
+ [Википедия](https://ru.wikipedia.org/wiki/)
+ [tokarchuk.ru](http://tokarchuk.ru/2012/08/indexes-classification/)
+ [Quizful](http://www.quizful.net/interview/sql/)
[Вопросы для собеседования](README.md)

@ -0,0 +1,120 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
Docker:
1. Что такое Docker?
2. Какие преимущества дает использование Docker?
3. Какая разница между контейнером и виртуальной машиной?
4. Какой дистрибутив Linux рекомендуется для использования Docker?
5. Как вы создаете Dockerfile?
6. Как использовать Docker Compose?
7. Как использовать Docker Swarm?
8. Как можно управлять контейнерами с помощью командной строки?
9. Как можно работать с образами Docker?
10. Каким образом можно настроить сетевые интерфейсы контейнера Docker?
11. Как можно ограничивать доступ к ресурсам контейнера?
12. Как можно настроить порты для работы контейнеров?
13. Почему Docker рекомендуется для микросервисной архитектуры?
14. Как можно масштабировать приложение, используя Docker?
15. Как вы управляете логами Docker?
16. Каким образом можно конфигурировать переменные окружения контейнера?
17. Каким образом можно сохранять данные контейнера?
18. Как можно обновлять Docker-образы?
19. Как можно проверять целостность Docker-образов?
20. Каким образом можно проверять наличие новых версий образов Docker в репозитории?
21. Как вы отладчик приложения, работающего в контейнере Docker?
22. Как вы тестируете приложение, работающее в контейнере Docker?
23. Как вы используете Docker для разработки локально?
24. Как вы используете Docker для развертывания приложения в продакшене?
25. Каким образом можно обеспечить безопасность контейнеров Docker?
26. Как можно управлять версиями Docker-образов?
27. Как можно резервировать контейнеры Docker?
28. Каким образом можно настроить доступ к базе данных в контейнере Docker?
29. Каким образом можно управлять зависимостями приложения в контейнере Docker?
30. Каким образом можно использовать Docker с Kubernetes?
31. Каким образом можно использовать Docker в AWS ECS?
32. Каким образом можно использовать Docker в Azure Container Service?
33. Каким образом можно использовать Docker в Google Cloud Platform?
34. Каким образом можно использовать Docker с Mesos?
35. Каким образом можно использовать Docker с Nomad?
36. Как можно настроить мониторинг контейнеров Docker?
37. Каким образом можно управлять сборкой Docker-образов на CI/CD сервере?
38. Каким образом можно использовать Docker для тестирования безопасности приложения?
39. Каким образом можно использовать Docker для развертывания кластера Cassandra?
40. Каким образом можно использовать Docker для развертывания кластера Kafka?
41. Каким образом можно использовать Docker для развертывания кластера ElasticSearch?
42. Каким образом можно использовать Docker для развертывания кластера RabbitMQ?
43. Каким образом можно использовать Docker для развертывания кластера PostgresSQL?
44. Как можно использовать Docker для создания переносимых окружений разработки?
45. Каким образом можно использовать Docker для создания переносимых окружений QA?
46. Каким образом можно использовать Docker для создания переносимых окружений в рамках DevOps?
47. Как можно управлять изменениями Dockerfile в рамках системы контроля версий?
48. Каким образом можно использовать Docker для развертывания многоконтейнерных приложений?
49. Как можно настроить доступ к файловой системе хоста из контейнера Docker?
50. Каким образом можно настроить сетевое взаимодействие между контейнерами Docker?
51. Каким образом можно использовать Docker для тестирования конфигурации приложения?
52. Какой процесс запускается в контейнере Docker?
53. Каким образом можно использовать Docker для подготовки учебного окружения?
54. Каким образом можно использовать Docker для портирования приложения на новый сервер?
55. Каким образом можно использовать Docker для развертывания приложения на нескольких серверах?
56. Каким образом можно использовать Docker для тестирования масштабирования приложения?
57. Каким образом можно использовать Docker для выделения ресурсов на сервере?
58. Каким образом можно настроить удаленный доступ к контейнеру Docker?
59. Каким образом можно использовать Docker для развертывания приложения в Kubernetes?
60. Каким образом можно использовать Docker для развертывания приложения в OpenShift?
61. Каким образом можно использовать Docker для развертывания приложения в Rancher?
62. Каким образом можно использовать Docker для развертывания приложения на Heroku?
63. Каким образом можно использовать Docker для развертывания приложения в Digital Ocean?
64. Каким образом можно использовать Docker для развертывания приложения в Linode?
65. Каким образом можно использовать Docker для развертывания приложения на Amazon Web Services?
66. Каким образом можно использовать Docker для развертывания приложения на Google Cloud Platform?
67. Каким образом можно использовать Docker для развертывания приложения на Microsoft Azure?
68. Что такое Docker Hub?
69. Каким образом можно использовать Docker Hub для хранения образов Docker?
70. Каким образом можно использовать Docker Hub для совместной работы над проектами?
71. Каким образом можно создавать свои собственные репозитории Docker?
72. Каким образом можно настроить автоматическую сборку образов Docker в Docker Hub?
73. Каким образом можно работать с Docker-образами, которые не хранятся в Docker Hub?
74. Каким образом можно создавать приватные Docker-репозитории?
75. Каким образом можно использовать Docker-образы, которые безопасно хранят конфиденциальную информацию?
76. Как можно управлять доступом к Docker-репозиториям?
77. Каким образом можно использовать Docker для развертывания приложения на множестве серверов?
78. Каким образом можно использовать Docker для развертывания приложения в нескольких средах?
79. Каким образом можно использовать Docker для тестирования приложения на разных ОС?
80. Каким образом можно использовать Docker для развертывания приложения в одной среде, но на разных серверах?
81. Каким образом можно использовать Docker для тестирования обновлений приложения?
82. Каким образом можно использовать Docker для тестирования отказоустойчивости приложения?
83. Каким образом можно использовать Docker для уменьшения времени развертывания приложения?
84. Каким образом можно использовать Docker для уменьшения времени восстановления после сбоев?
85. Каким образом можно использовать Docker для тестирования безопасности приложения?
86. Каким образом можно использовать Docker для развертывания приложения на локальной машине?
87. Каким образом можно использовать Docker для развертывания приложения в облаке?
88. Каким образом можно использовать Docker для тестирования масштабируемости приложения?
89. Каким образом можно использовать Docker для быстрого развертывания инфраструктуры?
90. Каким образом можно использовать Docker для работы с базами данных?
91. Каким образом можно использовать Docker для разработки на нескольких языках программирования?
92. Каким образом можно использовать Docker для тестирования интеграции приложения?
93. Каким образом можно использовать Docker для тестирования производительности приложения?
94. Каким образом можно использовать Docker для создания и управления резервными копиями?
95. Каким образом можно использовать Docker для миграции приложения?
96. Каким образом можно использовать Docker для развертывания приложения, которое работает в связке с другими сервисами?
97. Каким образом можно использовать Docker для создания и управления микросервисами?
98. Каким образом можно использовать Docker для создания распределенной системы?
99. Каким образом можно использовать Docker для масштабирования приложения в автоматическом режиме?
100. Каким образом можно использовать Docker для развертывания простых приложений, таких как блоги и веб-сайты?

@ -0,0 +1,226 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
1. Что такое Hibernate и как вы с ним работали?
Hibernate - это фреймворк для работы с базами данных, который предоставляет высокоуровневый API для работы с объектами и базами данных. Он позволяет разработчикам работать с объектами вместо работы с SQL-запросами. Hibernate также предоставляет механизмы для управления транзакциями, кэшированием и оптимизацией производительности.
Я использовал Hibernate в нескольких проектах. В одном из проектов я использовал Hibernate для создания объектов и сохранения их в базе данных. Я также использовал Hibernate для выполнения запросов к базе данных и получения результатов в виде объектов. Я также использовал Hibernate для управления транзакциями, чтобы гарантировать целостность данных.
2. Какие преимущества использования Hibernate в своих проектах вы видите?
3. Какую базу данных вы обычно используете при работе с Hibernate?
4. Что такое ORM и какие ее преимущества?
5. Как настроить Hibernate для работы с несколькими базами данных?
6. Как бы вы реализовали связь многие-ко-многим с помощью Hibernate?
7. Какая версия Hibernate вам больше всего нравится и почему?
8. Почему нужно использовать Hibernate вместо написания SQL запросов вручную?
9. Как вы работаете с кэшем в Hibernate?
10. Какие типы связей поддерживает Hibernate?
11. Как можно настроить Hibernate для работы с процедурами хранимыми БД?
12. Как вы обычно тестируете код, использующий Hibernate?
13. Как вы обрабатываете ошибки Hibernate в своих проектах?
14. Какие книги или ресурсы по Hibernate вы можете порекомендовать?
15. Как настроить Hibernate для работы с кластеризованными серверами БД?
16. Как использовать Hibernate для преобразования данных из одного формата в другой?
17. Как настроить Hibernate для работы с различными форматами данных (XML, JSON)?
18. Какие фреймворки вы использовали в связке с Hibernate?
19. Как обеспечить безопасность при работе с Hibernate?
20. Какая ваша опытность работы с инструментами мониторинга производительности?
21. Какую структуру БД лучше всего использовать для работы с Hibernate?
22. Как вы обрабатываете большие объемы данных с помощью Hibernate?
23. Как управлять транзакциями в Hibernate?
24. Каким образом можно расширять функциональность Hibernate?
25. Какие особенности работы Hibernate в многопоточной среде нужно учитывать?
26. Как вы работаете с Batch операциями в Hibernate?
27. Как использовать Hibernate в качестве ORM-фреймворка для .NET?
28. Как создавать запросы на выборку данных с помощью Hibernate Criteria API?
29. Как настроить работу Hibernate в режиме lazy loading?
30. Как обработать проблемы, связанные с блокировкой таблицы при использовании Hibernate?
31. Как настроить Hibernate для работы с RDBMS, не поддерживаемых Hibernate "из коробки"?
32. Как работать с достаточно сложными запросами на выборку данных с помощью Hibernate Query Language?
33. Как использовать Hibernate в качестве ORM-фреймворка для NoSQL БД?
34. Как вы работаете с библиотеками масштабирования приложений со сложной логикой?
35. Как настроить Hibernate для работы с реляционными базами данных, которые не поддерживают транзакции?
36. Как обеспечить производительность при работе с большим числом записей в базе данных с помощью Hibernate?
37. Как создавать уникальные индексы на таблицы с помощью Hibernate аннотаций?
38. Как использовать Hibernate для работы с базами данных, расположенными на удаленных серверах?
39. Как упростить работу с Hibernate с помощью Spring Framework?
40. Как настроить Hibernate для работы с процедурамями, написанными на PL/SQL?
42. Какие проблемы могут возникнуть при работе Hibernate с большими объемами данных и как их решить?
43. Как использовать Hibernate для работы с несколькими БД одновременно?
44. Как продуктивно использовать кэш в Hibernate?
45. Какие преимущества и недостатки имеет Hibernate по сравнению с другими ORM-фреймворками?
46. Как работать с Hibernate в распределенных системах?
47. Как настроить Hibernate для работы с минимальной задержкой?
48. Как использовать Hibernate для работы с временными таблицами?
49. Как производить миграции базы данных с помощью Hibernate?
50. Как использовать Hibernate для работы с Cassandra?
51. Как обрабатывать ошибки при работе с Hibernate?
52. Как использовать Hibernate для работы с MongoDB?
53. Как оптимизировать работу Hibernate с большим количеством запросов?
54. Как создавать собственные аннотации Hibernate?
55. Как использовать Hibernate для работы с Couchbase?
56. Как работать с Hibernate в системах с высокой нагрузкой?
57. Как настроить Hibernate для работы с несколькими серверами БД?
58. Как использовать Hibernate для работы с HBase?
59. Как настроить Hibernate для работы с Elasticsearch?
60. Как использовать Hibernate для работы с Neo4j?
61. Как решать проблемы производительности при работе с Hibernate?
62. Как использовать Hibernate для работы с Solr?
63. Как настроить Hibernate для работы с ClickHouse?
64. Как использовать Hibernate для работы с Redis?
65. Как создавать запросы на изменение данных с помощью Hibernate?
66. Как использовать Hibernate для работы с Apache Ignite?
67. Как настроить Hibernate для работы с Vertica?
68. Как использовать Hibernate для работы с InfluxDB?
69. Как использовать Hibernate для работы с Aerospike?
70. Какие подходы используются для оптимизации работы Hibernate?
71. Как использовать Hibernate для работы с ArangoDB?
72. Как настроить Hibernate для работы с Yellowbrick?
73. Как использовать Hibernate для работы с Greenplum?
74. Как правильно использовать кэш в Hibernate?
75. Как использовать Hibernate для работы с Teradata?
76. Какие лучшие практики работы с Hibernate вы можете порекомендовать?
77. Как настроить Hibernate для работы с Amazon Redshift?
78. Как использовать Hibernate для работы с Pinot?
79. Как настроить Hibernate для работы с Google BigQuery?
80. Как использовать Hibernate для работы с Microsoft SQL Server?
81. Как правильно использовать инструменты мониторинга производительности в Hibernate?
82. Как настроить Hibernate для работы с Oracle DB?
83. Как использовать Hibernate для работы с PostgreSQL?
84. Как использовать Hibernate для работы с MySQL?
85. Как использовать Hibernate для работы с SQLite?
86. Как настроить Hibernate для работы с DB2?
87. Как использовать Hibernate для работы с Sybase?
88. Как настроить Hibernate для работы с Informix?
89. Как использовать Hibernate для работы с Firebird?
90. Какие ресурсы вы можете порекомендовать для изучения Hibernate?
91. Как использовать Hibernate для работы с Apache Cassandra?
92. Как работать с многопоточностью в Hibernate?
93. Как использовать Hibernate для работы с Apache Hadoop?
94. Как настроить Hibernate для работы с Apache Hive?
95. Как использовать Hibernate для работы с Apache Phoenix?
96. Как настроить Hibernate для работы с Apache Spark?
97. Как использовать Hibernate для работы с Apache Kafka?
98. Как настроить Hibernate для работы с Apache Flink?
99. Как использовать Hibernate для работы с Apache Druid?
100. Как использовать Hibernate для работы с CouchDB?
101. Как настроить Hibernate для работы с Amazon Aurora?
102. Как использовать Hibernate для работы с Google Cloud SQL?
103. Какие инструменты и библиотеки могут помочь в работе с Hibernate?
104. Как решать проблемы безопасности при работе с Hibernate?
105. Как использовать Hibernate для работы с Apache Cassandra как кэшем?
106. Какие подходы используются для тестирования Hibernate-приложений?
107. Как настроить Hibernate для работы с ClickHouse как кэшем?
108. Как использовать Hibernate для работы с Hazelcast?
109. Как использовать Hibernate для работы с Apache Geode?
110. Как использовать Hibernate для работы с Oracle Coherence?
111. Как использовать Hibernate для работы с Apache ZooKeeper?
112. Как использовать Hibernate для работы с Apache Pulsar?
113. Как использовать Hibernate для работы с Apache Beam?
114. Как настроить Hibernate для работы с Apache Kylin?
115. Как использовать Hibernate для работы с Apache Accumulo?
116. Как использовать Hibernate для работы с Apache Kudu?
117. Как настроить Hibernate для работы с Apache Impala?
118. Как использовать Hibernate для работы с Apache Ignite как кэшем?
119. Как использовать Hibernate для работы с Amazon DynamoDB?
120. Как использовать Hibernate для работы с Google Cloud Firestore?
121. Как использовать Hibernate для работы с Apache CouchDB как кэшем?
122. Как настроить Hibernate для работы с Amazon DocumentDB?
123. Как использовать Hibernate для работы с Google Cloud Bigtable?
124. Как использовать Hibernate для работы с Redis как кэшем?
125. Как использовать Hibernate для работы с MongoDB как кэшем?
126. Как использовать Hibernate для работы с Apache HBase как кэшем?
127. Как использовать Hibernate для работы с Apache Cassandra и Solr вместе?
128. Как использовать Hibernate для работы с Apache NiFi?
129. Как использовать Hibernate для работы с Apache Flink и Apache Kafka вместе?
130. Как использовать Hibernate для работы с Apache Spark и Apache Cassandra вместе?
131. Как использовать Hibernate для работы с Apache Beam и Google BigQuery вместе?
132. Как использовать Hibernate для работы с Apache Druid как кэшем?
133. Как использовать Hibernate для работы с Apache Phoenix как кэшем?
134. Как использовать Hibernate для работы с Apache Pulsar и Apache Flink вместе?
135. Как использовать Hibernate для работы с Apache Geode и Apache Kafka вместе?
136. Как использовать Hibernate для работы с Apache Kudu как кэшем?
137. Как использовать Hibernate для работы с Apache Impala как кэшем?
138. Как использовать Hibernate для работы с Apache Ignite и Apache Spark вместе?
139. Как использовать Hibernate для работы с Amazon ElastiCache?
140. Как использовать Hibernate для работы с Google Cloud Memorystore?
141. Как использовать Hibernate для работы с Apache Cassandra и Apache Spark вместе?
142. Как использовать Hibernate для работы с Apache Flink и Apache Druid вместе?
143. Как использовать Hibernate для работы с Apache Geode и Apache Ignite вместе?
144. Как использовать Hibernate для работы с Apache Pulsar и Apache Cassandra вместе?
145. Как использовать Hibernate для работы с Apache Kudu и Apache Spark вместе?
146. Как использовать Hibernate для работы с Apache Beam и Google Cloud Pub/Sub вместе?
147. Как использовать Hibernate для работы с Apache Phoenix и Apache HBase вместе?
148. Как использовать Hibernate для работы с Amazon Neptune?
149. Как использовать Hibernate для работы с Google Cloud Spanner?
150. Как использовать Hibernate для работы с Azure Cosmos DB?
151. Как настроить Hibernate для работы с кластером серверов базы данных?
152. Как обеспечить безопасность при работе с Hibernate?
153. Как использовать Hibernate для работы с графовыми базами данных, например, Neo4j?
154. Как использовать Hibernate для работы с временными рядами, например, InfluxDB?
155. Как использовать Hibernate для работы с NoSQL базами данных, например, MongoDB?
156. Как использовать Hibernate для работы с OLAP базами данных, например, Apache Kylin?
157. Как настроить Hibernate для работы с индексами полнотекстового поиска, например, Elasticsearch?
158. Как использовать Hibernate для работы с табличными базами данных, например, Apache Cassandra?
159. Как использовать Hibernate для работы с геоданными, например, Apache Solr?
160. Как использовать Hibernate для работы с Key-Value хранилищами, например, Redis?
161. Как настроить Hibernate для работы с Oracle RAC?
162. Как настроить Hibernate для работы с Microsoft SQL Server AlwaysOn?
163. Как использовать Hibernate для работы с Amazon Redshift Spectrum?
164. Как использовать Hibernate для работы с Google Cloud Dataflow?
165. Как использовать Hibernate для работы с Apache CouchDB как хранилищем данных?
166. Как использовать Hibernate для работы с Google Cloud Storage как хранилищем данных?
167. Как настроить Hibernate для работы с репликацией базы данных?
168. Как использовать Hibernate для работы с Apache Ignite и Apache Flink вместе в распределенных системах?
169. Как использовать Hibernate для работы с Apache Hadoop и Apache Hive вместе?
170. Как использовать Hibernate для работы с Apache HBase и Apache Phoenix вместе?
171. Как настроить Hibernate для работы с Apache Kudu и Apache Impala вместе?
172. Как использовать Hibernate для работы с Amazon S3 как хранилищем данных?
173. Как использовать Hibernate для работы с Apache Flink и Apache Pulsar вместе в распределенных системах?
174. Как использовать Hibernate для работы с Apache Cassandra и Apache Lucene вместе для полнотекстового поиска?
175. Как использовать Hibernate для работы с Apache Ignite и Apache Spark вместе в распределенных системах?
176. Как настроить Hibernate для работы с механизмом шардирования базы данных?
177. Как использовать Hibernate для работы с Azure HDInsight и Apache Hive вместе?
178. Как использовать Hibernate для работы с Apache HBase и Apache Phoenix вместе для OLTP?
179. Как настроить Hibernate для работы с Amazon Neptune и Gremlin API?
180. Как использовать Hibernate для работы с Couchbase и N1QL языком запросов?
181. Как использовать Hibernate для работы с геораспределенными базами данных, например, CockroachDB?
182. Как настроить Hibernate для работы с SQL Server Availability Groups?
183. Как использовать Hibernate для работы с Amazon DocumentDB и MongoDB API?
184. Как использовать Hibernate для работы с Google Cloud BigQuery и SQL языком запросов?
185. Как использовать Hibernate для работы с индексами временных рядов, например, TimescaleDB?
186. Как использовать Hibernate для работы с Apache Cassandra и Apache Spark вместе для OLAP?
187. Как использовать Hibernate для работы с Apache Druid и SQL языком запросов?
188. Как использовать Hibernate для работы с Google Cloud Datastore?
189. Как настроить Hibernate для работы с резервными копиями базы данных?
190. Как использовать Hibernate для работы с графовыми базами данных, например, Amazon Neptune?
191. Как использовать Hibernate для работы с ClickHouse и SQL языком запросов?
192. Как использовать Hibernate для работы с Google Cloud Spanner и SQL языком запросов?
193. Как использовать Hibernate для работы с Apache Cassandra и Apache ZooKeeper вместе для координации?
194. Как использовать Hibernate для работы с Google Cloud Pub/Sub?
195. Как использовать Hibernate для работы с Azure Cosmos DB и SQL языком запросов?
196. Как использовать Hibernate для работы с Amazon RDS Proxy?
197. Как использовать Hibernate для работы с Apple Core Data?
198. Как использовать Hibernate для работы с Apache Pulsar как хранилищем данных?
199. Как использовать Hibernate для работы с сервисами управления версиями данных, например, Liquibase или Flyway?
200. Как использовать Hibernate для работы с гибридными системами управления данными?

@ -0,0 +1,333 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# Потоки ввода/вывода в Java
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Потоки ввода/вывода в Java](#потоки-вводавывода-в-java)
- [В чём заключается разница между IO и NIO?](#в-чём-заключается-разница-между-io-и-nio)
- [Какие классы поддерживают чтение и запись потоков в компрессированном формате?](#какие-классы-поддерживают-чтение-и-запись-потоков-в-компрессированном-формате)
- [Какие особенности NIO вы знаете?](#какие-особенности-nio-вы-знаете)
- [Что такое _«каналы»_?](#что-такое-каналы)
- [Какие существуют виды потоков ввода/вывода?](#какие-существуют-виды-потоков-вводавывода)
- [Назовите основные классы потоков ввода/вывода.](#назовите-основные-классы-потоков-вводавывода)
- [В каких пакетах расположены классы потоков ввода/вывода?](#в-каких-пакетах-расположены-классы-потоков-вводавывода)
- [Какие подклассы класса `InputStream` вы знаете, для чего они предназначены?](#какие-подклассы-класса-inputstream-вы-знаете-для-чего-они-предназначены)
- [Для чего используется `PushbackInputStream`?](#для-чего-используется-pushbackinputstream)
- [Для чего используется `SequenceInputStream`?](#для-чего-используется-sequenceinputstream)
- [Какой класс позволяет читать данные из входного байтового потока в формате примитивных типов данных?](#какой-класс-позволяет-читать-данные-из-входного-байтового-потока-в-формате-примитивных-типов-данных)
- [Какие подклассы класса `OutputStream` вы знаете, для чего они предназначены?](#какие-подклассы-класса-outputstream-вы-знаете-для-чего-они-предназначены)
- [Какие подклассы класса `Reader` вы знаете, для чего они предназначены?](#какие-подклассы-класса-reader-вы-знаете-для-чего-они-предназначены)
- [Какие подклассы класса `Writer` вы знаете, для чего они предназначены?](#какие-подклассы-класса-writer-вы-знаете-для-чего-они-предназначены)
- [В чем отличие класса `PrintWriter` от `PrintStream`?](#в-чем-отличие-класса-printwriter-от-printstream)
- [Чем отличаются и что общего у `InputStream`, `OutputStream`, `Reader`, `Writer`?](#чем-отличаются-и-что-общего-у-inputstream-outputstream-reader-writer)
- [Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?](#какие-классы-позволяют-преобразовать-байтовые-потоки-в-символьные-и-обратно)
- [Какие классы позволяют ускорить чтение/запись за счет использования буфера?](#какие-классы-позволяют-ускорить-чтениезапись-за-счет-использования-буфера)
- [Какой класс предназначен для работы с элементами файловой системы?](#какой-класс-предназначен-для-работы-с-элементами-файловой-системы)
- [Какие методы класса `File` вы знаете?](#какие-методы-класса-file-вы-знаете)
- [Что вы знаете об интерфейсе `FileFilter`?](#что-вы-знаете-об-интерфейсе-filefilter)
- [Как выбрать все элементы определенного каталога по критерию (например, с определенным расширением)?](#как-выбрать-все-элементы-определенного-каталога-по-критерию-например-с-определенным-расширением)
- [Что вы знаете о `RandomAccessFile`?](#что-вы-знаете-о-randomaccessfile)
- [Какие режимы доступа к файлу есть у `RandomAccessFile`?](#какие-режимы-доступа-к-файлу-есть-у-randomaccessfile)
- [Какие классы поддерживают чтение и запись потоков в компрессированном формате?](#какие-классы-поддерживают-чтение-и-запись-потоков-в-компрессированном-формате-1)
- [Существует ли возможность перенаправить потоки стандартного ввода/вывода?](#существует-ли-возможность-перенаправить-потоки-стандартного-вводавывода)
- [Какой символ является разделителем при указании пути в файловой системе?](#какой-символ-является-разделителем-при-указании-пути-в-файловой-системе)
- [Что такое _«абсолютный путь»_ и _«относительный путь»_?](#что-такое-абсолютный-путь-и-относительный-путь)
- [Что такое _«символьная ссылка»_?](#что-такое-символьная-ссылка)
- [Источники](#источники)
[к оглавлению](#Потоки-вводавывода-в-java)
## В чём заключается разница между IO и NIO?
+ Java IO (input-output) является потокоориентированным, а Java NIO (new/non-blocking io) буфер-ориентированным. Потокоориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно. Данная информация нигде не кэшируются. Таким образом, невозможно произвольно двигаться по потоку данных вперед или назад. В Java NIO данные сначала считываются в буфер, что дает больше гибкости при обработке данных.
+ Потоки ввода/вывода в Java IO являются блокирующими. Это значит, что когда в потоке выполнения вызывается `read()` или `write()` метод любого класса из пакета `java.io.*`, происходит блокировка до тех пор, пока данные не будут считаны или записаны. Поток выполнения в данный момент не может делать ничего другого. Неблокирующий режим Java NIO позволяет запрашивать считанные данные из канала (channel) и получать только то, что доступно на данный момент, или вообще ничего, если доступных данных пока нет. Вместо того, чтобы оставаться заблокированным пока данные не станут доступными для считывания, поток выполнения может заняться чем-то другим. Тоже самое справедливо и для неблокирующего вывода. Поток выполнения может запросить запись в канал некоторых данных, но не дожидаться при этом пока они не будут полностью записаны.
+ В Java NIO имеются селекторы, которые позволяют одному потоку выполнения мониторить несколько каналов ввода. Т.е. существует возможность зарегистрировать несколько каналов с селектором, а потом использовать один поток выполнения для обслуживания каналов, имеющих доступные для обработки данные, или для выбора каналов, готовых для записи.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие классы поддерживают чтение и запись потоков в компрессированном формате?
+ DeflaterOutputStream - компрессия данных в формате deflate.
+ Deflater - компрессия данных в формат ZLIB
+ ZipOutputStream - потомок DeflaterOutputStream для компрессии данных в формат Zip.
+ GZIPOutputStream - потомок DeflaterOutputStream для компрессии данных в формат GZIP.
+ InflaterInputStream - декомпрессия данных в формате deflate.
+ Inflater - декомпрессия данных в формате ZLIB
+ ZipInputStream - потомок InflaterInputStream для декомпрессии данных в формате Zip.
+ GZIPInputStream - потомок InflaterInputStream для декомпрессии данных в формате GZIP.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие особенности NIO вы знаете?
+ __Каналы и селекторы__: NIO поддерживает различные типы каналов. Канал является абстракцией объектов более низкого уровня файловой системы (например, отображенные в памяти файлы и блокировки файлов), что позволяет передавать данные с более высокой скоростью. Каналы не блокируются и поэтому Java предоставляет еще такие инструменты, как селектор, который позволяет выбрать готовый канал для передачи данных, и сокет, который является инструментом для блокировки.
+ __Буферы__: имеет буферизация для всех классов-обёрток примитивов (кроме Boolean). Появился абстрактный класс Buffer, который предоставляет такие операции, как clear, flip, mark и т.д. Его подклассы предоставляют методы для получения и установки данных.
+ __Кодировки__: появились кодеры и декодеры для отображения байт и символов Unicode.
[к оглавлению](#Потоки-вводавывода-в-java)
## Что такое _«каналы»_?
Каналы (channels) это логические (не физические) порталы, абстракции объектов более низкого уровня файловой системы (например, отображенные в памяти файлы и блокировки файлов), через которые осуществляется ввод/вывод данных, а буферы являются источниками или приёмниками этих переданных данных. При организации вывода, данные, которые необходимо отправить, помещаются в буфер, который затем передается в канал. При вводе, данные из канала помещаются в заранее предоставленный буфер.
Каналы напоминают трубопроводы, по которым эффективно транспортируются данные между буферами байтов и сущностями по ту сторону каналов. Каналы это шлюзы, которые позволяют получить доступ к сервисам ввода/вывода операционной системы с минимальными накладными расходами, а буферы внутренние конечные точки этих шлюзов, используемые для передачи и приема данных.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие существуют виды потоков ввода/вывода?
## Назовите основные классы потоков ввода/вывода.
Разделяют два вида потоков ввода/вывода:
+ __байтовые__ - `java.io.InputStream`, `java.io.OutputStream`;
+ __символьные__ - `java.io.Reader`, `java.io.Writer`.
[к оглавлению](#Потоки-вводавывода-в-java)
## В каких пакетах расположены классы потоков ввода/вывода?
`java.io`, `java.nio`. Для работы с потоками компрессированных данных используются классы из пакета `java.util.zip`
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие подклассы класса `InputStream` вы знаете, для чего они предназначены?
+ `InputStream` - абстрактный класс, описывающий поток ввода;
+ `BufferedInputStream` - буферизованный входной поток;
+ `ByteArrayInputStream` позволяет использовать буфер в памяти (массив байтов) в качестве источника данных для входного потока;
+ `DataInputStream` - входной поток для байтовых данных, включающий методы для чтения стандартных типов данных Java;
+ `FileInputStream` - входной поток для чтения информации из файла;
+ `FilterInputStream` - абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства;
+ `ObjectInputStream` - входной поток для объектов;
+ `StringBufferInputStream` превращает строку (`String`) во входной поток данных `InputStream`;
+ `PipedInputStream` реализует понятие входного канала;
+ `PrintStream` - выходной поток, включающий методы `print()` и `println()`;
+ `PushbackInputStream` - разновидность буферизации, обеспечивающая чтение байта с последующим его возвратом в поток, позволяет «заглянуть» во входной поток и увидеть, что оттуда поступит в следующий момент, не извлекая информации.
+ `SequenceInputStream` используется для слияния двух или более потоков `InputStream` в единый.
[к оглавлению](#Потоки-вводавывода-в-java)
## Для чего используется `PushbackInputStream`?
Разновидность буферизации, обеспечивающая чтение байта с последующим его возвратом в поток. Класс `PushbackInputStream` представляет механизм «заглянуть» во входной поток и увидеть, что оттуда поступит в следующий момент, не извлекая информации.
У класса есть дополнительный метод unread().
[к оглавлению](#Потоки-вводавывода-в-java)
## Для чего используется `SequenceInputStream`?
Класс `SequenceInputStream` позволяет сливать вместе несколько экземпляров класса `InputStream`. Конструктор принимает в качестве аргумента либо пару объектов класса `InputStream`, либо интерфейс `Enumeration`.
Во время работы класс выполняет запросы на чтение из первого объекта класса `InputStream` и до конца, а затем переключается на второй. При использовании интерфейса работа продолжится по всем объектам класса `InputStream`. По достижении конца, связанный с ним поток закрывается. Закрытие потока, созданного объектом класса `SequenceInputStream`, приводит к закрытию всех открытых потоков.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какой класс позволяет читать данные из входного байтового потока в формате примитивных типов данных?
Класс `DataInputStream` представляет поток ввода и предназначен для записи данных примитивных типов, таких, как `int`, `double` и т.д. Для каждого примитивного типа определен свой метод для считывания:
+ `boolean readBoolean()`: считывает из потока булевое однобайтовое значение
+ `byte readByte()`: считывает из потока 1 байт
+ `char readChar()`: считывает из потока значение `char`
+ `double readDouble()`: считывает из потока 8-байтовое значение `double`
+ `float readFloat()`: считывает из потока 4-байтовое значение `float`
+ `int readInt()`: считывает из потока целочисленное значение `int`
+ `long readLong()`: считывает из потока значение `long`
+ `short readShort()`: считывает значение `short`
+ `String readUTF()`: считывает из потока строку в кодировке UTF-8
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие подклассы класса `OutputStream` вы знаете, для чего они предназначены?
+ `OutputStream` - это абстрактный класс, определяющий потоковый байтовый вывод;
+ `BufferedOutputStream` - буферизированный выходной поток;
+ `ByteArrayOutputStream` - все данные, посылаемые в этот поток, размещаются в предварительно созданном буфере;
+ `DataOutputStream` - выходной поток байт, включающий методы для записи стандартных типов данных Java;
+ `FileOutputStream` - запись данных в файл на физическом носителе;
+ `FilterOutputStream` - абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства;
+ `ObjectOutputStream` - выходной поток для записи объектов;
+ `PipedOutputStream` реализует понятие выходного канала.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие подклассы класса `Reader` вы знаете, для чего они предназначены?
+ `Reader` - абстрактный класс, описывающий символьный ввод;
+ `BufferedReader` - буферизованный входной символьный поток;
+ `CharArrayReader` - входной поток, который читает из символьного массива;
+ `FileReader` - входной поток, читающий файл;
+ `FilterReader` - абстрактный класс, предоставляющий интерфейс для классов-надстроек;
+ `InputStreamReader`- входной поток, транслирующий байты в символы;
+ `LineNumberReader` - входной поток, подсчитывающий строки;
+ `PipedReader` - входной канал;
+ `PushbackReader` - входной поток, позволяющий возвращать символы обратно в поток;
+ `StringReader` - входной поток, читающий из строки.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие подклассы класса `Writer` вы знаете, для чего они предназначены?
+ `Writer` - абстрактный класс, описывающий символьный вывод;
+ `BufferedWriter` - буферизованный выходной символьный поток;
+ `CharArrayWriter` - выходной поток, который пишет в символьный массив;
+ `FileWriter` - выходной поток, пишущий в файл;
+ `FilterWriter` - абстрактный класс, предоставляющий интерфейс для классов-надстроек;
+ `OutputStreamWriter` - выходной поток, транслирующий байты в символы;
+ `PipedWriter` - выходной канал;
+ `PrintWriter` - выходной поток символов, включающий методы `print()` и `println()`;
+ `StringWriter` - выходной поток, пишущий в строку;
[к оглавлению](#Потоки-вводавывода-в-java)
## В чем отличие класса `PrintWriter` от `PrintStream`?
Прежде всего, в классе `PrintWriter` применен усовершенствованный способ работы с символами Unicode и другой механизм буферизации вывода: в классе PrintStream буфер вывода сбрасывался всякий раз, когда вызывался метод `print()` или `println()`, а при использовании класса `PrintWriter` существует возможность отказаться от автоматического сброса буферов, выполняя его явным образом при помощи метода `flush()`.
Кроме того, методы класса `PrintWriter` никогда не создают исключений. Для проверки ошибок необходимо явно вызвать метод `checkError()`.
[к оглавлению](#Потоки-вводавывода-в-java)
## Чем отличаются и что общего у `InputStream`, `OutputStream`, `Reader`, `Writer`?
+ `InputStream` и его наследники - совокупность для получения байтовых данных из различных источников;
+ `OutputStream` и его наследники - набор классов определяющих потоковый байтовый вывод;
+ `Reader` и его наследники определяют потоковый ввод символов Unicode;
+ `Writer` и его наследники определяют потоковый вывод символов Unicode.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?
+ `OutputStreamWriter` — «мост» между классом `OutputStream` и классом `Writer`. Символы, записанные в поток, преобразовываются в байты.
+ `InputStreamReader` — аналог для чтения. При помощи методов класса `Reader` читаются байты из потока `InputStream` и далее преобразуются в символы.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие классы позволяют ускорить чтение/запись за счет использования буфера?
+ `BufferedInputStream(InputStream in)`/`BufferedInputStream(InputStream in, int size)`,
+ `BufferedOutputStream(OutputStream out)`/`BufferedOutputStream(OutputStream out, int size)`,
+ `BufferedReader(Reader r)`/`BufferedReader(Reader in, int sz)`,
+ `BufferedWriter(Writer out)`/`BufferedWriter(Writer out, int sz)`
[к оглавлению](#Потоки-вводавывода-в-java)
## Какой класс предназначен для работы с элементами файловой системы?
`File` работает непосредственно с файлами и каталогами. Данный класс позволяет создавать новые элементы и получать информацию существующих: размер, права доступа, время и дату создания, путь к родительскому каталогу.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие методы класса `File` вы знаете?
Наиболее используемые методы класса `File`:
+ `boolean createNewFile()`: делает попытку создать новый файл;
+ `boolean delete()`: делает попытку удалить каталог или файл;
+ `boolean mkdir()`: делает попытку создать новый каталог;
+ `boolean renameTo(File dest)`: делает попытку переименовать файл или каталог;
+ `boolean exists()`: проверяет, существует ли файл или каталог;
+ `String getAbsolutePath()`: возвращает абсолютный путь для пути, переданного в конструктор объекта;
+ `String getName()`: возвращает краткое имя файла или каталога;
+ `String getParent()`: возвращает имя родительского каталога;
+ `boolean isDirectory()`: возвращает значение `true`, если по указанному пути располагается каталог;
+ `boolean isFile()`: возвращает значение `true`, если по указанному пути находится файл;
+ `boolean isHidden()`: возвращает значение `true`, если каталог или файл являются скрытыми;
+ `long length()`: возвращает размер файла в байтах;
+ `long lastModified()`: возвращает время последнего изменения файла или каталога;
+ `String[] list()`: возвращает массив файлов и подкаталогов, которые находятся в определенном каталоге;
+ `File[] listFiles()`: возвращает массив файлов и подкаталогов, которые находятся в определенном каталоге.
[к оглавлению](#Потоки-вводавывода-в-java)
## Что вы знаете об интерфейсе `FileFilter`?
Интерфейс `FileFilter` применяется для проверки, попадает ли объект `File` под некоторое условие. Этот интерфейс содержит единственный метод `boolean accept(File pathName)`. Этот метод необходимо переопределить и реализовать. Например:
```java
public boolean accept(final File file) {
return file.isExists() && file.isDirectory();
}
```
[к оглавлению](#Потоки-вводавывода-в-java)
## Как выбрать все элементы определенного каталога по критерию (например, с определенным расширением)?
Метод `File.listFiles()` возвращает массив объектов `File`, содержащихся в каталоге. Метод может принимать в качестве параметра объект класса, реализующего `FileFilter`. Это позволяет включить список только те элементы, для которые метода `accept` возвращает `true` (критерием может быть длина имени файла или его расширение).
[к оглавлению](#Потоки-вводавывода-в-java)
## Что вы знаете о `RandomAccessFile`?
Класс `java.io.RandomAccessFile` обеспечивает чтение и запись данных в произвольном месте файла. Он не является частью иерархии `InputStream` или `OutputStream`. Это полностью отдельный класс, имеющий свои собственные (в большинстве своем _native_) методы. Объяснением этого может быть то, что `RandomAccessFile` имеет во многом отличающееся поведение по сравнению с остальными классами ввода/вывода так как позволяет, в пределах файла, перемещаться вперед и назад.
`RandomAccessFile` имеет такие специфические методы как:
+ `getFilePointer()` для определения текущего местоположения в файле;
+ `seek()` для перемещения на новую позицию в файле;
+ `length()` для выяснения размера файла;
+ `setLength()` для установки размера файла;
+ `skipBytes()` для того, чтобы попытаться пропустить определённое число байт;
+ `getChannel()` для работы с уникальным файловым каналом, ассоциированным с заданным файлом;
+ методы для выполнения обычного и форматированного вывода из файла (`read()`, `readInt()`, `readLine()`, `readUTF()` и т.п.);
+ методы для обычной или форматированной записи в файл с прямым доступом (`write()`, `writeBoolean()`, `writeByte()` и т.п.).
Так же следует отметить, что конструкторы `RandomAccessFile` требуют второй аргумент, указывающий необходимый режим доступа к файлу - только чтение (`"r"`), чтение и запись (`"rw"`) или иную их разновидность.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие режимы доступа к файлу есть у `RandomAccessFile`?
+ `"r"` открывает файл только для чтения. Запуск любых методов записи данных приведет к выбросу исключения `IOException`.
+ `"rw"` открывает файл для чтения и записи. Если файл еще не создан, то осуществляется попытка создать его.
+ `"rws"` открывает файл для чтения и записи подобно `"rw"`, но требует от системы при каждом изменении содержимого файла или метаданных синхронно записывать эти изменения на физический носитель.
+ `"rwd"` открывает файл для чтения и записи подобно `"rws"`, но требует от системы синхронно записывать изменения на физический носитель только при каждом изменении содержимого файла. Если изменяются метаданные, синхронная запись не требуется.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какие классы поддерживают чтение и запись потоков в компрессированном формате?
+ `DeflaterOutputStream` - компрессия данных в формате deflate.
+ `Deflater` - компрессия данных в формат ZLIB
+ `ZipOutputStream` - потомок `DeflaterOutputStream` для компрессии данных в формат Zip.
+ `GZIPOutputStream` - потомок `DeflaterOutputStream` для компрессии данных в формат GZIP.
+ `InflaterInputStream` - декомпрессия данных в формате deflate.
+ `Inflater` - декомпрессия данных в формате ZLIB
+ `ZipInputStream` - потомок `InflaterInputStream` для декомпрессии данных в формате Zip.
+ `GZIPInputStream` - потомок `InflaterInputStream` для декомпрессии данных в формате GZIP.
[к оглавлению](#Потоки-вводавывода-в-java)
## Существует ли возможность перенаправить потоки стандартного ввода/вывода?
Класс `System` позволяет вам перенаправлять стандартный ввод, вывод и поток вывода ошибок, используя простой вызов статического метода:
+ `setIn(InputStream)` - для ввода;
+ `setOut(PrintStream)` - для вывода;
+ `setErr(PrintStream)` - для вывода ошибок.
[к оглавлению](#Потоки-вводавывода-в-java)
## Какой символ является разделителем при указании пути в файловой системе?
Для различных операционных систем символ разделителя различается. Для Windows это `\`, для Linux - `/`.
В Java получить разделитель для текущей операционной системы можно через обращение к статическому полю `File.separator`.
[к оглавлению](#Потоки-вводавывода-в-java)
## Что такое абсолютный путь»_ и относительный путь»_?
__Абсолютный (полный) путь__ — это путь, который указывает на одно и то же место в файловой системе, вне зависимости от текущей рабочей директории или других обстоятельств. Полный путь всегда начинается с корневого каталога.
__Относительный путь__ представляет собой путь по отношению к текущему рабочему каталогу пользователя или активного приложения.
[к оглавлению](#Потоки-вводавывода-в-java)
## Что такое символьная ссылка»_?
__Символьная (символическая) ссылка__ (также «симлинк», Symbolic link) — специальный файл в файловой системе, в котором, вместо пользовательских данных, содержится путь к файлу, который должен быть открыт при попытке обратиться к данной ссылке (файлу). Целью ссылки может быть любой объект: например, другая ссылка, файл, каталог или даже несуществующий файл (в последнем случае, при попытке открыть его, должно выдаваться сообщение об отсутствии файла).
Символьные ссылки используются для более удобной организации структуры файлов на компьютере, так как:
+ позволяют для одного файла или каталога иметь несколько имён и различных атрибутов;
+ свободны от некоторых ограничений, присущих жёстким ссылкам (последние действуют только в пределах одной файловой системы (одного раздела) и не могут ссылаться на каталоги).
[к оглавлению](#Потоки-вводавывода-в-java)
# Источники
+ [Quizful](http://www.quizful.net/post/java-nio-tutorial)
+ [Хабрахабр](https://habrahabr.ru/post/235585/)
+ [Освой программирование играючи](http://developer.alexanderklimov.ru/android/java/io.php)
+ [Metanit](http://metanit.com/java/tutorial/6.1.php)
+ [javastudy.ru](http://javastudy.ru/interview/input-output/)
+ [Bruce Eckel «Thinking in Java»](http://iais.kemsu.ru/odocs/java/Chapter11.html)
[Вопросы для собеседования](README.md)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,179 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
JSP (оглавление)
1. Что такое jsp и зачем он нужен?
2. Расскажите об этапах жизненного цикла jsp.
3. Расскажите о методах жизненного цикла jsp.
4. Как закомментировать код в jsp?
5. Какие есть способы вставки java кода в jsp страницу?
6. Почему не рекомендуется использовать скриптовые элементы в jsp?
7. Какие неявные, внутренние объекты есть на jsp странице?
8. Что вы знаете о PageContext?
9. Как можно запретить использование скриптов и java кода на jsp странице?
10. Что вы знаете о jsp тегах?
11. Что вы знаете о языке выражений jsp (JSP Expression Language EL)?
12. Назовите неявные, внутренние объекты JSP EL и их отличия от объектов jsp.
13. Как узнать http метод использую JSP EL?
14. Что такое JSTL (Jsp Standard tag library)?
15. На какие категории можно разделить JSTL теги, приведите примеры.
16. Что вы знаете о написании пользовательских jsp тегов?
17. Как можно обработать ошибки jsp страниц?
18. Как происходит обработка ошибок с помощью jstl?
19. Как деактивировать использование EL на JSP?
20. Можно ли использовать javascript на jsp странице?
21. Всегда ли создается объект сессии на jsp странице, можно ли отключить его создание?
22. Как можно расширить функциональность jsp?
Servlet (оглавление)
277. Какова структура веб-проекта?
278. Что такое сервлет?
279. Что такое контейнер сервлетов?
280. Каковы задачи, функциональность контейнера сервлетов?
281. Что вы знаете о сервлет фильтрах?
282. Зачем нужны слушатели в сервлетах?
283. Когда вы будете использовать фильтры а когда слушатели?
284. Как обработать исключения, выброшенные другим сервлетом в приложении?
285. Что такое дискриптор развертывания?
286. Как реализовать запуск сервлета с запуском приложения?
287. Что представляет собой объект ServletConfig?
288. Что представляет собой объект ServletContext?
289. В чем отличия ServletContext и ServletConfig?
290. Что такое Request Dispatcher?
291. Как можно создать блокировку (deadlock) в сервлете?
292. Как получить адрес сервлета на сервере?
293. Как получить информацию о сервере с сервлета?
294. Как получить ip адрес клиента на сервере?
295. Что вы знаете о классах обертках (wrapper) для сервлетов?
296. Каков жизненный цикл сервлета и когда какие методы вызываются?
297. Какие методы необходимо определить при создании сервлетов?
298. В каком случае вы будете переопределять метод service()?
299. Есть ли смысл определить конструктор для сервлета, как лучше инициализировать данные?
300. В чем отличия GenericServlet и HttpServlet?
301. Как вызватьиз сервлета другой сервлет этого же и другого приложения?
302. Что вы знаете и в чем отличия методов forward() и sendRedirect()?
303. Стоит ли волноваться о “многопоточной безопасности” работая с сервлетами?
304. Что такое servlet scope (область видимости время жизни) и какие вы знаете?
305. Что вы знаете и зачем нужны методы java.net.URLEncoder.encode() и decode()?
306. Зачем нужны и чем отличаются методы encodeUrl() и encodeRedirectUrl()?
307. Что такое «сервлет»?
308. В чем заключаются преимущества технологии сервлетов над CGI (Common Gateway Interface)?
309. Какова структура веб-проекта?
310. Что такое «контейнер сервлетов»?
311. Зачем нужны сервера приложений, если есть контейнеры сервлетов?
312. Как контейнер сервлетов управляет жизненным циклом сервлета, когда и какие методы вызываются?
313. Что такое «дескриптор развертывания»?
314. Какие действия необходимо проделать при создании сервлетов?
315. В каком случае требуется переопределять метод service()?
316. Есть ли смысл определять для сервлета конструктор? Каким образом лучше инициализировать данные?
317. Почему необходимо переопределить только init() метод без аргументов?
318. Какие наиболее распространенные задачи выполняются в контейнере сервлетов?
319. Что вы знаете о сервлетных фильтрах?
320. Зачем в сервлетах используются различные listener?
321. Когда стоит использовать фильтры сервлетов, а когда слушателей?
322. Как реализовать запуск сервлета одновременно с запуском приложения?
323. Как обработать в приложении исключения, выброшенные другим сервлетом?
324. Что представляет собой ServletConfig?
325. Что представляет собой ServletContext?
326. В чем отличия ServletContext и ServletConfig?
327. Для чего нужен интерфейс ServletResponse?
328. Для чего нужен интерфейс ServletRequest?
329. Что такое Request Dispatcher?
330. Как из одного сервлета вызвать другой сервлет?
331. Чем отличается sendRedirect() от forward()?
332. Для чего используются атрибуты сервлетов и как происходит работа с ними?
333. Каким образом можно допустить в сервлете deadlock?
334. Как получить реальное расположение сервлета на сервере?
335. Как получить информацию о сервере из сервлета?
336. Как получить IP адрес клиента на сервере?
337. Какие классы-обертки для сервлетов вы знаете?
338. В чем отличия GenericServlet и HttpServlet?
339. Почему HttpServlet класс объявлен как абстрактный?
340. Какие основные методы присутствуют в классе HttpServlet?
341. Стоит ли волноваться о многопоточной безопасности работая с сервлетами?
342. Какой метод HTTP не является неизменяемым?
343. Какие есть методы отправки данных с клиента на сервер?
344. В чем разница между методами GET и POST?
345. В чем разница между PrintWriter и ServletOutputStream?
346. Можно ли одновременно использовать в сервлете PrintWriter и ServletOutputStream?
347. Расскажите об интерфейсе SingleThreadModel.
348. Что означает URL encoding? Как это осуществить в Java?
349. Какие различные методы управления сессией в сервлетах вы знаете?
350. Что такое cookies?
351. Какие методы для работы с cookies предусмотрены в сервлетах?
352. Что такое URL Rewriting?
353. Зачем нужны и чем отличаются методы encodeURL() и encodeRedirectURL()?
354. Что такое «сессия»?
355. Как уведомить объект в сессии, что сессия недействительна или закончилась?
356. Какой существует эффективный способ удостоверится, что все сервлеты доступны только для пользователя с верной сессией?
357. Как мы можем обеспечить transport layer security для нашего веб приложения?
358. Как организовать подключение к базе данных, обеспечить журналирование в сервлете?
359. Какие основные особенности появились в спецификации Servlet 3?
360. Какие способы аутентификации доступны сервлету?
361. Что такое Java Server Pages (JSP)?
362. Зачем нужен JSP?
363. Опишите, как обрабатываются JSP страницы, начиная от запроса к серверу, заканчивая ответом пользователю.
364. Расскажите об этапах (фазах) жизненного цикла JSP.
365. Расскажите о методах жизненного цикла JSP.
366. Какие методы жизненного цикла JSP могут быть переопределены?
367. Как можно предотвратить прямой доступ к JSP странице из браузера?
368. Какая разница между динамическим и статическим содержимым JSP?
369. Как закомментировать код в JSP?
370. Какие существуют основные типы тегов JSP?
371. Что вы знаете о действиях JSP (Action tag и JSP Action Elements).
372. Взаимодействие JSP - сервлет - JSP.
373. Какие области видимости переменных существуют в JSP?
374. Какие неявные, внутренние объекты и методы есть на JSP странице?
375. Какие неявные объекты не доступны в обычной JSP странице?
376. Что вы знаете о PageContext и какие преимущества его использования?
377. Как сконфигурировать параметры инициализации для JSP?
378. Почему не рекомендуется использовать скриплеты (скриптовые элементы) в JSP?
379. Можно ли определить класс внутри JSP страницы?
380. Что вы знаете о Языке выражений JSP (JSP Expression Language EL)?
381. Какие типы EL операторов вы знаете?
382. Назовите неявные, внутренние объекты JSP EL и их отличия от объектов JSP.
383. Как отключить возможность использования EL в JSP?
384. Как узнать тип HTTP метода используя JSP EL?
385. Что такое JSTL (JSP Standard tag library)?
386. Из каких групп тегов состоит библиотека JSTL?
387. Какая разница между <c:set> и <jsp:useBean>?
388. Чем отличается <c:import> от <jsp:include> и директивы <%@include %>?
389. Как можно расширить функциональность JSP?
390. Что вы знаете о написании пользовательских JSP тегов?
391. Приведите пример использования собственных тегов.
392. Как сделать перенос строки в HTML средствами JSP?
393. Почему не нужно конфигурировать стандартные JSP теги в web.xml?
394. Как можно обработать ошибки JSP страниц?
395. Как происходит обработка ошибок с помощью JSTL?
396. Как конфигурируется JSP в дескрипторе развертывания.
397. Можно ли использовать Javascript на JSP странице?
398. Всегда ли создается объект сессии на JSP странице, можно ли отключить его создание?
399. Какая разница между JSPWriter и сервлетным PrintWriter?
400. Опишите общие практические принципы работы с JSP.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,130 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# Журналирование
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Журналирование](#журналирование)
- [Какие существуют типы логов?](#какие-существуют-типы-логов)
- [Из каких частей состоит система журналирования log4j?](#из-каких-частей-состоит-система-журналирования-log4j)
- [Что такое _Logger_ в log4j?](#что-такое-logger-в-log4j)
- [Что такое _Appender_ в log4j?](#что-такое-appender-в-log4j)
- [Что такое _Layout_ в log4j?](#что-такое-layout-в-log4j)
- [Перечислите уровни журналирования в log4j? Назовите порядок их приоритетности.](#перечислите-уровни-журналирования-в-log4j-назовите-порядок-их-приоритетности)
- [Какие существуют способы конфигурирования log4j?](#какие-существуют-способы-конфигурирования-log4j)
- [Источники](#источники)
## Какие существуют типы логов?
+ системы (System);
+ безопасности (Security);
+ приложения (Application, Buisness).
> Пользователь входит в приложение, проверяется пароль. Это действие относится к безопасности (Security). Дальше он запускает какой-нибудь модуль. Это событие уровня приложения (Application). Модуль при старте обращается к другому модулю за какими-то дополнительными данными, производит какие-либо еще вызовы это уже системные действия (System).
[к оглавлению](#Журналирование)
## Из каких частей состоит система журналирования log4j?
Система журналирования состоит из трёх основных частей:
+ управляющей журналированием - __logger__;
+ добавляющей в журнал - __appender__;
+ определяющей формат добавления - __layout__.
[к оглавлению](#Журналирование)
## Что такое _Logger_ в log4j?
__Logger__ представляет собой объект класса `org.apache.log4j.Logger`, который используется как управляющий интерфейс для журналирования сообщений с возможностью задавать уровень детализации. Именно logger проверяет нужно ли обрабатывать сообщение и если журналирование необходимо, то сообщение передаётся в appender, если нет - система завершает обработку данного сообщения.
[к оглавлению](#Журналирование)
## Что такое _Appender_ в log4j?
__Appender__ - это именованный объект журнала событий, реализующий интерфейс `org.apache.log4j.Appender` и добавляющий события в журнал. Appender вызывает разные вспомогательные инструменты - компоновщик, фильтр, обработчик ошибок (если они определены и необходимы). В ходе этой работы окончательно устанавливается необходимость записи сообщения, сообщению придаются окончательные содержание и форма.
В log4j журнал может представлять:
+ консоль;
+ файл;
+ сокет;
+ объект класса реализующего `java.io.Writer` или `java.io.OutputStream`;
+ JDBC хранилище;
+ тему (topic) JMS;
+ NT Event Log;
+ SMTP;
+ Syslog;
+ Telnet.
Наиболее часто используемые log4j appender-ы:
+ `org.apache.log4j.ConsoleAppender` - вывод в консоль;
+ `org.apache.log4j.FileAppender` - добавление в файл;
+ `org.apache.log4j.DailyRollingFileAppender` - добавление в файл с обновлением файла через заданный промежуток времени;
+ `org.apache.log4j.RollingFileAppender` - добавление в файл с обновлением файла по достижению определенного размера;
+ `org.apache.log4j.varia.ExternallyRolledFileAppender` - расширение _RollingFileAppender_ обновляющее файл по команде принятой с заданного порта;
+ `org.apache.log4j.net.SMTPAppender` - сообщение по SMTP;
+ `org.apache.log4j.AsyncAppender` - позволяет, используя отдельный поток, организовать асинхронную работу, когда сообщения фиксируются лишь при достижении определенного уровня заполненности промежуточного буфера.
+ `org.apache.log4j.nt.NTEventLogAppender` - добавление в NT Event Log;
+ `org.apache.log4j.net.SyslogAppender` - добавление в Syslog;
+ `org.apache.log4j.jdbc.JDBCAppender` - запись в хранилище JDBC;
+ `org.apache.log4j.lf5.LF5Appender` - сообщение передаётся в специальный GUI интерфейс LogFactor5
+ `org.apache.log4j.net.SocketAppender` - трансляция сообщения по указанному адресу и порту;
+ `org.apache.log4j.net.SocketHubAppender` - рассылка сообщения сразу нескольким удалённым серверам соединённым по заданному порту;
+ `org.apache.log4j.net.TelnetAppender` - отсылка сообщения по протоколу Telenet;
+ `org.apache.log4j.net.JMSAppender` - добавление сообщения в JMS.
[к оглавлению](#Журналирование)
## Что такое _Layout_ в log4j?
__Layout__ - наследник класса `org.apache.log4j.Layout` предоставляющий возможность форматирования сообщения перед добавлением в журнал.
В log4j существуют следующие типы layout-ов:
+ `org.apache.log4j.SimpleLayout` - на выходе получается строка содержащая лишь уровень вывода и сообщение;
+ `org.apache.log4j.HTMLLayout` - форматирует сообщение в виде элемента HTML-таблицы;
+ `org.apache.log4j.xml.XMLLayout` - компанует сообщение в виде XML формате;
+ `org.apache.log4j.TTCCLayout` - на выходе сообщение дополняется информацией о времени, потоке, имени логгера и вложенном диагностическом контексте;
+ `org.apache.log4j.PatternLayout` / `org.apache.log4j.EnhancedPatternLayout` - настройка форматирования сообщения при помощи шаблона заданного пользователем.
[к оглавлению](#Журналирование)
## Перечислите уровни журналирования в log4j? Назовите порядок их приоритетности.
+ __OFF__ - отсутствие журналирования;
+ __FATAL__ - фатальная ошибка;
+ __ERROR__ - ошибка;
+ __WARN__ - предупреждение;
+ __INFO__ - информация;
+ __DEBUG__ - детальная информация для отладки;
+ __TRACE__ трассировка всех сообщений.
Между уровнями логирования установлен следующий порядок приоритетов:
`OFF < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < ALL`
[к оглавлению](#Журналирование)
## Какие существуют способы конфигурирования log4j?
Для того, чтобы log4j начал работать нужно предоставить ему конфигурацию. Это можно сделать несколькими путями:
+ Создать конфигурацию программно, т.е. получить logger, определить уровень журналирования, прикрепить appender и задать способ форматирования.
+ Указать файл или URL как аргумент при запуске java-машины `-Dlog4j.configuration=путь/к/файлу/конфигурации`, а затем прочитать его в программе при помощи `PropertyConfigurator.configure(...)`/ `DOMConfigurator.configure(...)` для формата `.properties` или `XML` соответственно.
+ Загрузить конфигурацию из файла в формате `XML` или `.properties`: log4j ищет файл конфигурации в classpath. Сначала ищется файл `log4j.xml` и, если таковой не найден, - файл `log4j.properties`.
[к оглавлению](#Журналирование)
# Источники
+ [Quizful](http://www.quizful.net/)
+ [Skipy](http://skipy.ru/useful/logging.html#log4j_concepts_logger)
[Вопросы для собеседования](README.md)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,782 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# Шаблоны проектирования
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Шаблоны проектирования](#шаблоны-проектирования)
- [Что такое _«шаблон проектирования»_?](#что-такое-шаблон-проектирования)
- [Назовите основные характеристики шаблонов.](#назовите-основные-характеристики-шаблонов)
- [Типы шаблонов проектирования.](#типы-шаблонов-проектирования)
- [Приведите примеры основных шаблонов проектирования.](#приведите-примеры-основных-шаблонов-проектирования)
- [Приведите примеры порождающих шаблонов проектирования.](#приведите-примеры-порождающих-шаблонов-проектирования)
- [Абстрактная фабрика](#абстрактная-фабрика)
- [Строитель Builder](#строитель-builder)
- [Фабричный метод](#фабричный-метод)
- [Прототип Prototype](#прототип-prototype)
- [Синглтон Singleton](#синглтон-singleton)
- [Приведите примеры структурных шаблонов проектирования.](#приведите-примеры-структурных-шаблонов-проектирования)
- [Приведите примеры поведенческих шаблонов проектирования.](#приведите-примеры-поведенческих-шаблонов-проектирования)
- [Что такое _«антипаттерн»_? Какие антипаттерны вы знаете?](#что-такое-антипаттерн-какие-антипаттерны-вы-знаете)
- [Что такое _Dependency Injection_?](#что-такое-dependency-injection)
- [Источники](#источники)
## Что такое _«шаблон проектирования»_?
__Шаблон (паттерн) проектирования (design pattern)__ — это проверенное и готовое к использованию решение. Это не класс и не библиотека, которую можно подключить к проекту, это нечто большее - он не зависит от языка программирования, не является законченным образцом, который может быть прямо преобразован в код и может быть реализован по разному в разных языках программирования.
Плюсы использования шаблонов:
+ снижение сложности разработки за счёт готовых абстракций для решения целого класса проблем.
+ облегчение коммуникации между разработчиками, позволяя ссылаться на известные шаблоны.
+ унификация деталей решений: модулей и элементов проекта.
+ возможность отыскав удачное решение, пользоваться им снова и снова.
+ помощь в выборе выбрать наиболее подходящего варианта проектирования.
Минусы:
+ слепое следование некоторому выбранному шаблону может привести к усложнению программы.
+ желание попробовать некоторый шаблон в деле без особых на то оснований.
[к оглавлению](#Шаблоны-проектирования)
## Назовите основные характеристики шаблонов.
+ __Имя__ - все шаблоны имеют уникальное имя, служащее для их идентификации;
+ __Назначение__ назначение данного шаблона;
+ __Задача__ - задача, которую шаблон позволяет решить;
+ __Способ решения__ - способ, предлагаемый в шаблоне для решения задачи в том контексте, где этот шаблон был найден;
+ __Участники__ - сущности, принимающие участие в решении задачи;
+ __Следствия__ - последствия от использования шаблона как результат действий, выполняемых в шаблоне;
+ __Реализация__ - возможный вариант реализации шаблона.
[к оглавлению](#Шаблоны-проектирования)
## Типы шаблонов проектирования.
+ Основные (Fundamental) - основные строительные блоки других шаблонов. Большинство других шаблонов использует эти шаблоны в той или иной форме.
+ Порождающие шаблоны (Creational) — шаблоны проектирования, которые абстрагируют процесс создание экземпляра. Они позволяют сделать систему независимой от способа создания, композиции и представления объектов. Шаблон, порождающий классы, использует наследование, чтобы изменять созданный объект, а шаблон, порождающий объекты, делегирует создание объектов другому объекту.
+ Структурные шаблоны (Structural) определяют различные сложные структуры, которые изменяют интерфейс уже существующих объектов или его реализацию, позволяя облегчить разработку и оптимизировать программу.
+ Поведенческие шаблоны (Behavioral) определяют взаимодействие между объектами, увеличивая таким образом его гибкость.
[к оглавлению](#Шаблоны-проектирования)
## Приведите примеры основных шаблонов проектирования.
+ __Делегирование (Delegation pattern)__ - Сущность внешне выражает некоторое поведение, но в реальности передаёт ответственность за выполнение этого поведения связанному объекту.
+ __Функциональный дизайн (Functional design)__ - Гарантирует, что каждая сущность имеет только одну обязанность и исполняет её с минимумом побочных эффектов на другие.
+ __Неизменяемый интерфейс (Immutable interface)__ - Создание неизменяемого объекта.
+ __Интерфейс (Interface)__ - Общий метод структурирования сущностей облегчающий их понимание.
+ __Интерфейс-маркер (Marker interface)__ - В качестве атрибута (как пометки объектной сущности) применяется наличие или отсутствие реализации интерфейса-маркера. В современных языках программирования вместо этого применяются атрибуты или аннотации.
+ __Контейнер свойств (Property container)__ - Позволяет добавлять дополнительные свойства сущности в контейнер внутри себя, вместо расширения новыми свойствами.
+ __Канал событий (Event channel)__ - Создаёт централизованный канал для событий. Использует сущность-представитель для подписки и сущность-представитель для публикации события в канале. Представитель существует отдельно от реального издателя или подписчика. Подписчик может получать опубликованные события от более чем одной сущности, даже если он зарегистрирован только на одном канале.
[к оглавлению](#Шаблоны-проектирования)
## Приведите примеры порождающих шаблонов проектирования.
+ __Абстрактная фабрика (Abstract factory)__ - (Фабрика фабрик) это порождающий паттерн проектирования, который позволяет создавать семейства связанных объектов, не привязываясь к конкретным классам создаваемых объектов. Пример:
+ __Строитель (Builder)__ - это порождающий паттерн проектирования, который позволяет создавать сложные объекты пошагово. Строитель даёт возможность использовать один и тот же код строительства для получения разных представлений объектов. Пример: StringBuilder
+ __Фабричный метод (Factory method)__ - это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов.
+ __Прототип (Prototype)__ - это порождающий паттерн проектирования, который позволяет копировать объекты, не вдаваясь в подробности их реализации.
+ __Одиночка (Singleton)__ - это порождающий паттерн проектирования, который гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.
[к оглавлению](#Шаблоны-проектирования)
## Абстрактная фабрика
Представьте, что вы пишете симулятор мебельного магазина. Ваш код содержит:
1) Семейство зависимых продуктов. Скажем, Кресло + Диван + Столик.
2) Несколько вариаций этого семейства. Например, продукты Кресло, Диван и Столик представлены в трёх разных стилях: Ар-деко, Викторианском и Модерне.
Вам нужен такой способ создавать объекты продуктов, чтобы они сочетались с другими продуктами того же семейства. Это важно, так как клиенты расстраиваются, если получают несочетающуюся мебель. Кроме того, вы не хотите вносить изменения в существующий код при добавлении новых продуктов или семейcтв в программу. Поставщики часто обновляют свои каталоги, и вы бы не хотели менять уже написанный код каждый раз при получении новых моделей мебели.
__Решение__
Для начала паттерн Абстрактная фабрика предлагает выделить общие интерфейсы для отдельных продуктов, составляющих семейства. Так, все вариации кресел получат общий интерфейс Кресло, все диваны реализуют интерфейс Диван и так далее.
Далее вы создаёте абстрактную фабрику — общий интерфейс, который содержит методы создания всех продуктов семейства (например, создатьКресло, создатьДиван и создатьСтолик). Эти операции должны возвращать абстрактные типы продуктов, представленные интерфейсами, которые мы выделили ранее — Кресла, Диваны и Столики.
Для каждой вариации семейства продуктов мы должны создать свою собственную фабрику, реализовав абстрактный интерфейс. Фабрики создают продукты одной вариации. Например, ФабрикаМодерн будет возвращать только КреслаМодерн,ДиваныМодерн и СтоликиМодерн.
Клиентский код должен работать как с фабриками, так и с продуктами только через их общие интерфейсы. Это позволит подавать в ваши классы любой тип фабрики и производить любые продукты, ничего не ломая.
```java
// Этот паттерн предполагает, что у вас есть несколько семейств
// продуктов, находящихся в отдельных иерархиях классов
// (Button/Checkbox). Продукты одного семейства должны иметь
// общий интерфейс.
interface Button is
method paint()
// Семейства продуктов имеют те же вариации (macOS/Windows).
class WinButton implements Button is
method paint() is
// Отрисовать кнопку в стиле Windows.
class MacButton implements Button is
method paint() is
// Отрисовать кнопку в стиле macOS.
interface Checkbox is
method paint()
class WinCheckbox implements Checkbox is
method paint() is
// Отрисовать чекбокс в стиле Windows.
class MacCheckbox implements Checkbox is
method paint() is
// Отрисовать чекбокс в стиле macOS.
// Абстрактная фабрика знает обо всех абстрактных типах
// продуктов.
interface GUIFactory is
method createButton():Button
method createCheckbox():Checkbox
// Каждая конкретная фабрика знает и создаёт только продукты
// своей вариации.
class WinFactory implements GUIFactory is
method createButton():Button is
return new WinButton()
method createCheckbox():Checkbox is
return new WinCheckbox()
// Несмотря на то, что фабрики оперируют конкретными классами,
// их методы возвращают абстрактные типы продуктов. Благодаря
// этому фабрики можно взаимозаменять, не изменяя клиентский
// код.
class MacFactory implements GUIFactory is
method createButton():Button is
return new MacButton()
method createCheckbox():Checkbox is
return new MacCheckbox()
// Для кода, использующего фабрику, не важно, с какой конкретно
// фабрикой он работает. Все получатели продуктов работают с
// ними через общие интерфейсы.
class Application is
private field factory: GUIFactory
private field button: Button
constructor Application(factory: GUIFactory) is
this.factory = factory
method createUI()
this.button = factory.createButton()
method paint()
button.paint()
// Приложение выбирает тип конкретной фабрики и создаёт её
// динамически, исходя из конфигурации или окружения.
class ApplicationConfigurator is
method main() is
config = readApplicationConfigFile()
if (config.OS == "Windows") then
factory = new WinFactory()
else if (config.OS == "Mac") then
factory = new MacFactory()
else
throw new Exception("Error! Unknown operating system.")
Application app = new Application(factory)
```
__Применимость__
Когда бизнес-логика программы должна работать с разными видами связанных друг с другом продуктов, не завися от конкретных классов продуктов. Абстрактная фабрика скрывает от клиентского кода подробности того, как и какие конкретно объекты будут созданы. Но при этом клиентский код может работать со всеми типами создаваемых продуктов, поскольку их общий интерфейс был заранее определён.
Когда в программе уже используется Фабричный метод, но очередные изменения предполагают введение новых типов продуктов. В хорошей программе каждый класс отвечает только за одну вещь. Если класс имеет слишком много фабричных методов, они способны затуманить его основную функцию. Поэтому имеет смысл вынести всю логику создания продуктов в отдельную иерархию классов, применив абстрактную фабрику.
__Шаги реализации__
+ Создайте таблицу соотношений типов продуктов к вариациям семейств продуктов.
+ Сведите все вариации продуктов к общим интерфейсам.
+ Определите интерфейс абстрактной фабрики. Он должен иметь фабричные методы для создания каждого из типов продуктов.
+ Создайте классы конкретных фабрик, реализовав интерфейс абстрактной фабрики. Этих классов должно быть столько же, сколько и вариаций семейств продуктов.
+ Измените код инициализации программы так, чтобы она создавала определённую фабрику и передавала её в клиентский код.
+ Замените в клиентском коде участки создания продуктов через конструктор вызовами соответствующих методов фабрики.
__Преимущества и недостатки__
+ Гарантирует сочетаемость создаваемых продуктов.
+ Избавляет клиентский код от привязки к конкретным классам продуктов.
+ Выделяет код производства продуктов в одно место, упрощая поддержку кода.
+ Упрощает добавление новых продуктов в программу.
+ Реализует принцип открытости/закрытости.
+ - Усложняет код программы из-за введения множества дополнительных классов.
+ - Требует наличия всех типов продуктов в каждой вариации.
## Строитель Builder
Представьте сложный объект, требующий кропотливой пошаговой инициализации множества полей и вложенных объектов. Код инициализации таких объектов обычно спрятан внутри монструозного конструктора с десятком параметров. Либо ещё хуже — распылён по всему клиентскому коду.
Например, давайте подумаем о том, как создать объект Дом. Чтобы построить стандартный дом, нужно поставить 4 стены, установить двери, вставить пару окон и положить крышу. Но что, если вы хотите дом побольше да посветлее, имеющий сад, бассейн и прочее добро? Самое простое решение — расширить класс Дом, создав подклассы для всех комбинаций параметров дома. Проблема такого подхода — это громадное количество классов, которые вам придётся создать. Каждый новый параметр, вроде цвета обоев или материала кровли, заставит вас создавать всё больше и больше классов для перечисления всех возможных вариантов. Чтобы не плодить подклассы, вы можете подойти к решению с другой стороны. Вы можете создать гигантский конструктор Дома, принимающий уйму параметров для контроля над создаваемым продуктом. Действительно, это избавит вас от подклассов, но приведёт к другой проблеме. Большая часть этих параметров будет простаивать, а вызовы конструктора будут выглядеть монструозно из-за длинного списка параметров. К примеру, далеко не каждый дом имеет бассейн, поэтому параметры, связанные с бассейнами, будут простаивать бесполезно в 99% случаев.
__Решение__
Паттерн Строитель предлагает вынести конструирование объекта за пределы его собственного класса, поручив это дело отдельным объектам, называемым строителями. Паттерн предлагает разбить процесс конструирования объекта на отдельные шаги (например, построитьСтены, вставитьДвери и другие). Чтобы создать объект, вам нужно поочерёдно вызывать методы строителя. Причём не нужно запускать все шаги, а только те, что нужны для производства объекта определённой конфигурации.
Вы можете пойти дальше и выделить вызовы методов строителя в отдельный класс, называемый _директором_. В этом случае директор будет задавать порядок шагов строительства, а строитель — выполнять их.
```java
// Строитель может создавать различные продукты, используя один
// и тот же процесс строительства.
class Car is
// Автомобили могут отличаться комплектацией: типом
// двигателя, количеством сидений, могут иметь или не иметь
// GPS и систему навигации и т. д. Кроме того, автомобили
// могут быть городскими, спортивными или внедорожниками.
class Manual is
// Руководство пользователя для данной конфигурации
// автомобиля.
// Интерфейс строителя объявляет все возможные этапы и шаги
// конфигурации продукта.
interface Builder is
method reset()
method setSeats(...)
method setEngine(...)
method setTripComputer(...)
method setGPS(...)
// Все конкретные строители реализуют общий интерфейс по-своему.
class CarBuilder implements Builder is
private field car:Car
method reset()
// Поместить новый объект Car в поле "car".
method setSeats(...) is
// Установить указанное количество сидений.
method setEngine(...) is
// Установить поданный двигатель.
method setTripComputer(...) is
// Установить поданную систему навигации.
method setGPS(...) is
// Установить или снять GPS.
method getResult():Car is
// Вернуть текущий объект автомобиля.
// В отличие от других порождающих паттернов, где продукты
// должны быть частью одной иерархии классов или следовать
// общему интерфейсу, строители могут создавать совершенно
// разные продукты, которые не имеют общего предка.
class CarManualBuilder implements Builder is
private field manual:Manual
method reset()
// Поместить новый объект Manual в поле "manual".
method setSeats(...) is
// Описать, сколько мест в машине.
method setEngine(...) is
// Добавить в руководство описание двигателя.
method setTripComputer(...) is
// Добавить в руководство описание системы навигации.
method setGPS(...) is
// Добавить в инструкцию инструкцию GPS.
method getResult():Manual is
// Вернуть текущий объект руководства.
// Директор знает, в какой последовательности нужно заставлять
// работать строителя, чтобы получить ту или иную версию
// продукта. Заметьте, что директор работает со строителем через
// общий интерфейс, благодаря чему он не знает тип продукта,
// который изготовляет строитель.
class Director is
method constructSportsCar(builder: Builder) is
builder.reset()
builder.setSeats(2)
builder.setEngine(new SportEngine())
builder.setTripComputer(true)
builder.setGPS(true)
// Директор получает объект конкретного строителя от клиента
// (приложения). Приложение само знает, какого строителя нужно
// использовать, чтобы получить определённый продукт.
class Application is
method makeCar() is
director = new Director()
CarBuilder builder = new CarBuilder()
director.constructSportsCar(builder)
Car car = builder.getResult()
CarManualBuilder builder = new CarManualBuilder()
director.constructSportsCar(builder)
// Готовый продукт возвращает строитель, так как
// директор чаще всего не знает и не зависит от
// конкретных классов строителей и продуктов.
Manual manual = builder.getResult()
```
__Область применения__
Когда вы хотите избавиться от «телескопического конструктора». Допустим, у вас есть один конструктор с десятью опциональными параметрами. Его неудобно вызывать, поэтому вы создали ещё десять конструкторов с меньшим количеством параметров. Всё, что они делают — это переадресуют вызов к базовому конструктору, подавая какие-то значения по умолчанию в параметры, которые пропущены в них самих.
Когда ваш код должен создавать разные представления какого-то объекта. Например, деревянные и железобетонные дома. Строитель можно применить, если создание нескольких представлений объекта состоит из одинаковых этапов, которые отличаются в деталях. Интерфейс строителей определит все возможные этапы конструирования. Каждому представлению будет соответствовать собственный класс-строитель. А порядок этапов строительства будет задавать класс-директор.
Когда вам нужно собирать сложные составные объекты, например, деревья Компоновщика. Строитель конструирует объекты пошагово, а не за один проход. Более того, шаги строительства можно выполнять рекурсивно. А без этого не построить древовидную структуру, вроде Компоновщика. Заметьте, что Строитель не позволяет посторонним объектам иметь доступ к конструируемому объекту, пока тот не будет полностью готов. Это предохраняет клиентский код от получения незаконченных «битых» объектов.
__Шаги реализации__
+ Убедитесь в том, что создание разных представлений объекта можно свести к общим шагам.
+ Опишите эти шаги в общем интерфейсе строителей.
+ Для каждого из представлений объекта-продукта создайте по одному классу-строителю и реализуйте их методы строительства.
+ Не забудьте про метод получения результата. Обычно конкретные строители определяют собственные методы получения результата строительства. Вы не можете описать эти методы в интерфейсе строителей, поскольку продукты не обязательно должны иметь общий базовый класс или интерфейс. Но вы всегда сможете добавить метод получения результата в общий интерфейс, если ваши строители производят однородные продукты с общим предком.
+ Подумайте о создании класса директора. Его методы будут создавать различные конфигурации продуктов, вызывая разные шаги одного и того же строителя.
+ Клиентский код должен будет создавать и объекты строителей, и объект директора. Перед началом строительства клиент должен связать определённого строителя с директором. Это можно сделать либо через конструктор, либо через сеттер, либо подав строителя напрямую в строительный метод директора.
+ Результат строительства можно вернуть из директора, но только если метод возврата продукта удалось поместить в общий интерфейс строителей. Иначе вы жёстко привяжете директора к конкретным классам строителей.
__Преимущества и недостатки__
+ Позволяет создавать продукты пошагово.
+ Позволяет использовать один и тот же код для создания различных продуктов.
+ Изолирует сложный код сборки продукта от его основной бизнес-логики.
+ - Усложняет код программы из-за введения дополнительных классов.
+ - Клиент будет привязан к конкретным классам строителей, так как в интерфейсе строителя может не быть метода получения результата.
## Фабричный метод
Представьте, что вы создаёте программу управления грузовыми перевозками. Сперва вы рассчитываете перевозить товары только на автомобилях. Поэтому весь ваш код работает с объектами класса Грузовик.
В какой-то момент ваша программа становится настолько известной, что морские перевозчики выстраиваются в очередь и просят добавить поддержку морской логистики в программу. Отличные новости, правда?! Но как насчёт кода? Большая часть существующего кода жёстко привязана к классам Грузовиков. Чтобы добавить в программу классы морских Судов, понадобится перелопатить всю программу. Более того, если вы потом решите добавить в программу ещё один вид транспорта, то всю эту работу придётся повторить. В итоге вы получите ужасающий код, наполненный условными операторами, которые выполняют то или иное действие, в зависимости от класса транспорта.
__Решение__
Паттерн Фабричный метод предлагает создавать объекты не напрямую, используя оператор new, а через вызов особого фабричного метода. Не пугайтесь, объекты всё равно будут создаваться при помощи new, но делать это будет фабричный метод.
На первый взгляд, это может показаться бессмысленным: мы просто переместили вызов конструктора из одного конца программы в другой. Но теперь вы сможете переопределить фабричный метод в подклассе, чтобы изменить тип создаваемого продукта.
Чтобы эта система заработала, все возвращаемые объекты должны иметь общий интерфейс. Подклассы смогут производить объекты различных классов, следующих одному и тому же интерфейсу.
Например, классы Грузовик и Судно реализуют интерфейс Транспорт с методом доставить. Каждый из этих классов реализует метод по-своему: грузовики везут грузы по земле, а суда — по морю. Фабричный метод в классе ДорожнойЛогистики вернёт объект-грузовик, а класс МорскойЛогистики — объект-судно.
Для клиента фабричного метода нет разницы между этими объектами, так как он будет трактовать их как некий абстрактный Транспорт. Для него будет важно, чтобы объект имел метод доставить, а как конкретно он работает — не важно.
```java
// Паттерн Фабричный метод применим тогда, когда в программе
// есть иерархия классов продуктов.
interface Button is
method render()
method onClick(f)
class WindowsButton implements Button is
method render(a, b) is
// Отрисовать кнопку в стиле Windows.
method onClick(f) is
// Навесить на кнопку обработчик событий Windows.
class HTMLButton implements Button is
method render(a, b) is
// Вернуть HTML-код кнопки.
method onClick(f) is
// Навесить на кнопку обработчик события браузера.
// Базовый класс фабрики. Заметьте, что "фабрика" — это всего
// лишь дополнительная роль для класса. Скорее всего, он уже
// имеет какую-то бизнес-логику, в которой требуется создание
// разнообразных продуктов.
class Dialog is
method render() is
// Чтобы использовать фабричный метод, вы должны
// убедиться в том, что эта бизнес-логика не зависит от
// конкретных классов продуктов. Button — это общий
// интерфейс кнопок, поэтому все хорошо.
Button okButton = createButton()
okButton.onClick(closeDialog)
okButton.render()
// Мы выносим весь код создания продуктов в особый метод,
// который назвают "фабричным".
abstract method createButton():Button
// Конкретные фабрики переопределяют фабричный метод и
// возвращают из него собственные продукты.
class WindowsDialog extends Dialog is
method createButton():Button is
return new WindowsButton()
class WebDialog extends Dialog is
method createButton():Button is
return new HTMLButton()
class Application is
field dialog: Dialog
// Приложение создаёт определённую фабрику в зависимости от
// конфигурации или окружения.
method initialize() is
config = readApplicationConfigFile()
if (config.OS == "Windows") then
dialog = new WindowsDialog()
else if (config.OS == "Web") then
dialog = new WebDialog()
else
throw new Exception("Error! Unknown operating system.")
// Если весь остальной клиентский код работает с фабриками и
// продуктами только через общий интерфейс, то для него
// будет не важно, какая фабрика была создана изначально.
method main() is
this.initialize()
dialog.render()
```
__Применимость__
Когда заранее неизвестны типы и зависимости объектов, с которыми должен работать ваш код. Фабричный метод отделяет код производства продуктов от остального кода, который эти продукты использует. Благодаря этому, код производства можно расширять, не трогая основной. Так, чтобы добавить поддержку нового продукта, вам нужно создать новый подкласс и определить в нём фабричный метод, возвращая оттуда экземпляр нового продукта.
Когда вы хотите дать возможность пользователям расширять части вашего фреймворка или библиотеки. Пользователи могут расширять классы вашего фреймворка через наследование. Но как сделать так, чтобы фреймворк создавал объекты из этих новых классов, а не из стандартных? Решением будет дать пользователям возможность расширять не только желаемые компоненты, но и классы, которые создают эти компоненты. А для этого создающие классы должны иметь конкретные создающие методы, которые можно определить. Например, вы используете готовый UI-фреймворк для своего приложения. Но вот беда — требуется иметь круглые кнопки, вместо стандартных прямоугольных. Вы создаёте класс RoundButton. Но как сказать главному классу фреймворка UIFramework, чтобы он теперь создавал круглые кнопки, вместо стандартных? Для этого вы создаёте подкласс UIWithRoundButtons из базового класса фреймворка, переопределяете в нём метод создания кнопки (а-ля createButton) и вписываете туда создание своего класса кнопок. Затем используете UIWithRoundButtons вместо стандартного UIFramework.
Когда вы хотите экономить системные ресурсы, повторно используя уже созданные объекты, вместо порождения новых. Такая проблема обычно возникает при работе с тяжёлыми ресурсоёмкими объектами, такими, как подключение к базе данных, файловой системе и т. д. Представьте, сколько действий вам нужно совершить, чтобы повторно использовать существующие объекты:
+ Сначала вам следует создать общее хранилище, чтобы хранить в нём все создаваемые объекты.
+ При запросе нового объекта нужно будет заглянуть в хранилище и проверить, есть ли там неиспользуемый объект.
+ А затем вернуть его клиентскому коду.
+ Но если свободных объектов нет — создать новый, не забыв добавить его в хранилище.
Весь этот код нужно куда-то поместить, чтобы не засорять клиентский код. Самым удобным местом был бы конструктор объекта, ведь все эти проверки нужны только при создании объектов. Но, увы, конструктор всегда создаёт новые объекты, он не может вернуть существующий экземпляр. Значит, нужен другой метод, который бы отдавал как существующие, так и новые объекты. Им и станет фабричный метод.
__Шаги реализации__
+ Приведите все создаваемые продукты к общему интерфейсу.
+ В классе, который производит продукты, создайте пустой фабричный метод. В качестве возвращаемого типа укажите общий интерфейс продукта.
+ Затем пройдитесь по коду класса и найдите все участки, создающие продукты. Поочерёдно замените эти участки вызовами фабричного метода, перенося в него код создания различных продуктов. В фабричный метод, возможно, придётся добавить несколько параметров, контролирующих, какой из продуктов нужно создать. На этом этапе фабричный метод, скорее всего, будет выглядеть удручающе. В нём будет жить большой условный оператор, выбирающий класс создаваемого продукта. Но не волнуйтесь, мы вот-вот исправим это.
+ Для каждого типа продуктов заведите подкласс и переопределите в нём фабричный метод. Переместите туда код создания соответствующего продукта из суперкласса.
+ Если создаваемых продуктов слишком много для существующих подклассов создателя, вы можете подумать о введении параметров в фабричный метод, которые позволят возвращать различные продукты в пределах одного подкласса.
Например, у вас есть класс Почта с подклассами АвиаПочта и НаземнаяПочта, а также классы продуктов Самолёт, Грузовик и Поезд. Авиа соответствует Самолётам, но для НаземнойПочты есть сразу два продукта. Вы могли бы создать новый подкласс почты для поездов, но проблему можно решить и по-другому. Клиентский код может передавать в фабричный метод НаземнойПочты аргумент, контролирующий тип создаваемого продукта.
+ Если после всех перемещений фабричный метод стал пустым, можете сделать его абстрактным. Если в нём что-то осталось — не беда, это будет его реализацией по умолчанию.
__Преимущества и недостатки__
+ Избавляет класс от привязки к конкретным классам продуктов.
+ Выделяет код производства продуктов в одно место, упрощая поддержку кода.
+ Упрощает добавление новых продуктов в программу.
+ Реализует принцип открытости/закрытости.
+ - Может привести к созданию больших параллельных иерархий классов, так как для каждого класса продукта надо создать свой подкласс создателя.
## Прототип Prototype
У вас есть объект, который нужно скопировать. Как это сделать? Нужно создать пустой объект такого же класса, а затем поочерёдно скопировать значения всех полей из старого объекта в новый. Прекрасно! Но есть нюанс. Не каждый объект удастся скопировать таким образом, ведь часть его состояния может быть приватной, а значит — недоступной для остального кода программы. Но есть и другая проблема. Копирующий код станет зависим от классов копируемых объектов. Ведь, чтобы перебрать все поля объекта, нужно привязаться к его классу. Из-за этого вы не сможете копировать объекты, зная только их интерфейсы, а не конкретные классы.
__Решение__
Паттерн Прототип поручает создание копий самим копируемым объектам. Он вводит общий интерфейс для всех объектов, поддерживающих клонирование. Это позволяет копировать объекты, не привязываясь к их конкретным классам. Обычно такой интерфейс имеет всего один метод clone. Реализация этого метода в разных классах очень схожа. Метод создаёт новый объект текущего класса и копирует в него значения всех полей собственного объекта. Так получится скопировать даже приватные поля, так как большинство языков программирования разрешает доступ к приватным полям любого объекта текущего класса. Объект, который копируют, называется прототипом (откуда и название паттерна). Когда объекты программы содержат сотни полей и тысячи возможных конфигураций, прототипы могут служить своеобразной альтернативой созданию подклассов.В этом случае все возможные прототипы заготавливаются и настраиваются на этапе инициализации программы. Потом, когда программе нужен новый объект, она создаёт копию из приготовленного прототипа.
```java
// Базовый прототип.
abstract class Shape is
field X: int
field Y: int
field color: string
// Обычный конструктор.
constructor Shape() is
// ...
// Конструктор прототипа.
constructor Shape(source: Shape) is
this()
this.X = source.X
this.Y = source.Y
this.color = source.color
// Результатом операции клонирования всегда будет объект из
// иерархии классов Shape.
abstract method clone():Shape
// Конкретный прототип. Метод клонирования создаёт новый объект
// текущего класса, передавая в его конструктор ссылку на
// собственный объект. Благодаря этому операция клонирования
// получается атомарной — пока не выполнится конструктор, нового
// объекта ещё не существует. Но как только конструктор завершит
// работу, мы получим полностью готовый объект-клон, а не пустой
// объект, который нужно ещё заполнить.
class Rectangle extends Shape is
field width: int
field height: int
constructor Rectangle(source: Rectangle) is
// Вызов родительского конструктора нужен, чтобы
// скопировать потенциальные приватные поля, объявленные
// в родительском классе.
super(source)
this.width = source.width
this.height = source.height
method clone():Shape is
return new Rectangle(this)
class Circle extends Shape is
field radius: int
constructor Circle(source: Circle) is
super(source)
this.radius = source.radius
method clone():Shape is
return new Circle(this)
// Где-то в клиентском коде.
class Application is
field shapes: array of Shape
constructor Application() is
Circle circle = new Circle()
circle.X = 10
circle.Y = 10
circle.radius = 20
shapes.add(circle)
Circle anotherCircle = circle.clone()
shapes.add(anotherCircle)
// anotherCircle будет содержать точную копию circle.
Rectangle rectangle = new Rectangle()
rectangle.width = 10
rectangle.height = 20
shapes.add(rectangle)
method businessLogic() is
// Плюс Прототипа в том, что вы можете клонировать набор
// объектов, не зная их конкретные классы.
Array shapesCopy = new Array of Shapes.
// Например, мы не знаем, какие конкретно объекты
// находятся внутри массива shapes, так как он объявлен
// с типом Shape. Но благодаря полиморфизму, мы можем
// клонировать все объекты «вслепую». Будет выполнен
// метод clone того класса, которым является этот
// объект.
foreach (s in shapes) do
shapesCopy.add(s.clone())
// Переменная shapesCopy будет содержать точные копии
// элементов массива shapes.
```
__Применимость__
Когда ваш код не должен зависеть от классов копируемых объектов. Такое часто бывает, если ваш код работает с объектами, поданными извне через какой-то общий интерфейс. Вы не можете привязаться к их классам, даже если бы хотели, поскольку их конкретные классы неизвестны. Паттерн прототип предоставляет клиенту общий интерфейс для работы со всеми прототипами. Клиенту не нужно зависеть от всех классов копируемых объектов, а только от интерфейса клонирования.
Когда вы имеете уйму подклассов, которые отличаются начальными значениями полей. Кто-то мог создать все эти классы, чтобы иметь возможность легко порождать объекты с определённой конфигурацией. Паттерн прототип предлагает использовать набор прототипов, вместо создания подклассов для описания популярных конфигураций объектов. Таким образом, вместо порождения объектов из подклассов, вы будете копировать существующие объекты-прототипы, в которых уже настроено внутреннее состояние. Это позволит избежать взрывного роста количества классов в программе и уменьшить её сложность.
__Шаги реализации__
+ Создайте интерфейс прототипов с единственным методом clone. Если у вас уже есть иерархия продуктов, метод клонирования можно объявить непосредственно в каждом из её классов.
+ Добавьте в классы будущих прототипов альтернативный конструктор, принимающий в качестве аргумента объект текущего класса. Этот конструктор должен скопировать из поданного объекта значения всех полей, объявленных в рамках текущего класса, а затем передать выполнение родительскому конструктору, чтобы тот позаботился о полях, объявленных в суперклассе. Если ваш язык программирования не поддерживает перегрузку методов, то вам не удастся создать несколько версий конструктора. В этом случае копирование значений можно проводить и в другом методе, специально созданном для этих целей. Конструктор удобнее тем, что позволяет клонировать объект за один вызов.
+ Метод клонирования обычно состоит всего из одной строки: вызова оператора new с конструктором прототипа. Все классы, поддерживающие клонирование, должны явно определить метод clone, чтобы использовать собственный класс с оператором new. В обратном случае результатом клонирования станет объект родительского класса.
+ Опционально, создайте центральное хранилище прототипов. В нём удобно хранить вариации объектов, возможно, даже одного класса, но по-разному настроенных. Вы можете разместить это хранилище либо в новом фабричном классе, либо в фабричном методе базового класса прототипов. Такой фабричный метод должен на основании входящих аргументов искать в хранилище прототипов подходящий экземпляр, а затем вызывать его метод клонирования и возвращать полученный объект. Наконец, нужно избавиться от прямых вызовов конструкторов объектов, заменив их вызовами фабричного метода хранилища прототипов.
__Преимущества и недостатки__
+ Позволяет клонировать объекты, не привязываясь к их конкретным классам.
+ Меньше повторяющегося кода инициализации объектов.
+ Ускоряет создание объектов.
+ Альтернатива созданию подклассов для конструирования сложных объектов.
+ - Сложно клонировать составные объекты, имеющие ссылки на другие объекты.
## Синглтон Singleton
Одиночка решает сразу две проблемы, нарушая принцип единственной ответственности класса.
Гарантирует наличие единственного экземпляра класса. Чаще всего это полезно для доступа к какому-то общему ресурсу, например, базе данных. Представьте, что вы создали объект, а через некоторое время пробуете создать ещё один. В этом случае хотелось бы получить старый объект, вместо создания нового. Такое поведение невозможно реализовать с помощью обычного конструктора, так как конструктор класса всегда возвращает новый объект.
Предоставляет глобальную точку доступа. Это не просто глобальная переменная, через которую можно достучаться к определённому объекту. Глобальные переменные не защищены от записи, поэтому любой код может подменять их значения без вашего ведома. Но есть и другой нюанс. Неплохо бы хранить в одном месте и код, который решает проблему №1, а также иметь к нему простой и доступный интерфейс.
Интересно, что в наше время паттерн стал настолько известен, что теперь люди называют «одиночками» даже те классы, которые решают лишь одну из проблем, перечисленных выше.
__Решение__
Все реализации одиночки сводятся к тому, чтобы скрыть конструктор по умолчанию и создать публичный статический метод, который и будет контролировать жизненный цикл объекта-одиночки. Если у вас есть доступ к классу одиночки, значит, будет доступ и к этому статическому методу. Из какой точки кода вы бы его ни вызвали, он всегда будет отдавать один и тот же объект.
```java
// Класс одиночки определяет статический метод `getInstance`,
// который позволяет клиентам повторно использовать одно и то же
// подключение к базе данных по всей программе.
class Database is
// Поле для хранения объекта-одиночки должно быть объявлено
// статичным.
private static field instance: Database
// Конструктор одиночки всегда должен оставаться приватным,
// чтобы клиенты не могли самостоятельно создавать
// экземпляры этого класса через оператор `new`.
private constructor Database() is
// Здесь может жить код инициализации подключения к
// серверу баз данных.
// ...
// Основной статический метод одиночки служит альтернативой
// конструктору и является точкой доступа к экземпляру этого
// класса.
public static method getInstance() is
if (Database.instance == null) then
acquireThreadLock() and then
// На всякий случай ещё раз проверим, не был ли
// объект создан другим потоком, пока текущий
// ждал освобождения блокировки.
if (Database.instance == null) then
Database.instance = new Database()
return Database.instance
// Наконец, любой класс одиночки должен иметь какую-то
// полезную функциональность, которую клиенты будут
// запускать через полученный объект одиночки.
public method query(sql) is
// Все запросы к базе данных будут проходить через этот
// метод. Поэтому имеет смысл поместить сюда какую-то
// логику кеширования.
// ...
class Application is
method main() is
Database foo = Database.getInstance()
foo.query("SELECT ...")
// ...
Database bar = Database.getInstance()
bar.query("SELECT ...")
// Переменная "bar" содержит тот же объект, что и
// переменная "foo".
```
__Применимость__
Когда в программе должен быть единственный экземпляр какого-то класса, доступный всем клиентам (например, общий доступ к базе данных из разных частей программы). Одиночка скрывает от клиентов все способы создания нового объекта, кроме специального метода. Этот метод либо создаёт объект, либо отдаёт существующий объект, если он уже был создан.
Когда вам хочется иметь больше контроля над глобальными переменными. В отличие от глобальных переменных, Одиночка гарантирует, что никакой другой код не заменит созданный экземпляр класса, поэтому вы всегда уверены в наличии лишь одного объекта-одиночки. Тем не менее, в любой момент вы можете расширить это ограничение и позволить любое количество объектов-одиночек, поменяв код в одном месте (метод getInstance).
__Шаги реализации__
+ Добавьте в класс приватное статическое поле, которое будет содержать одиночный объект.
+ Объявите статический создающий метод, который будет использоваться для получения одиночки.
+ Добавьте «ленивую инициализацию» (создание объекта при первом вызове метода) в создающий метод одиночки.
+ Сделайте конструктор класса приватным.
+ В клиентском коде замените вызовы конструктора одиночка вызовами его создающего метода.
__Преимущества и недостатки__
+ Гарантирует наличие единственного экземпляра класса.
+ Предоставляет к нему глобальную точку доступа.
+ Реализует отложенную инициализацию объекта-одиночки.
+ - Нарушает принцип единственной ответственности класса.
+ - Маскирует плохой дизайн.
+ - Проблемы мультипоточности.
+ - Требует постоянного создания Mock-объектов при юнит-тестировании.
## Приведите примеры структурных шаблонов проектирования.
+ __Адаптер (Adapter)__ - это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе. Пример:
+ __Мост (Bridge)__ - это структурный паттерн проектирования, который разделяет один или несколько классов на две отдельные иерархии — абстракцию и реализацию, позволяя изменять их независимо друг от друга. Пример:
+ __Компоновщик (Composite)__ - это структурный паттерн проектирования, который позволяет сгруппировать множество объектов в древовидную структуру, а затем работать с ней так, как будто это единичный объект. Пример:
+ __Декоратор (Decorator)__ - это структурный паттерн проектирования, который позволяет динамически добавлять объектам новую функциональность, оборачивая их в полезные «обёртки» без использования наследования. Пример:
+ __Фасад (Facade)__ - это структурный паттерн проектирования, который предоставляет простой интерфейс к сложной системе классов, библиотеке или фреймворку. Пример:
+ __Приспособленец (Flyweight)__ - это структурный паттерн проектирования, который позволяет вместить бóльшее количество объектов в отведённую оперативную память. Легковес экономит память, разделяя общее состояние объектов между собой, вместо хранения одинаковых данных в каждом объекте. Представляющий себя как уникальный экземпляр в разных местах программы, но по факту не являющийся таковым. Пример:
+ __Заместитель (Proxy)__ - это структурный паттерн проектирования, который позволяет подставлять вместо реальных объектов специальные объекты-заменители. Эти объекты перехватывают вызовы к оригинальному объекту, позволяя сделать что-то до или после передачи вызова оригиналу. Пример: кеш в Hibernate, ленивая инициализация в Hibernate, транзакции в Spring
[к оглавлению](#Шаблоны-проектирования)
## Приведите примеры поведенческих шаблонов проектирования.
+ __Цепочка обязанностей (Chain of responsibility)__ - это поведенческий паттерн проектирования, который позволяет передавать запросы последовательно по цепочке обработчиков. Каждый последующий обработчик решает, может ли он обработать запрос сам и стоит ли передавать запрос дальше по цепи.
+ __Команда (Command)__ - это поведенческий паттерн проектирования, который превращает запросы в объекты, позволяя передавать их как аргументы при вызове методов, ставить запросы в очередь, логировать их, а также поддерживать отмену операций.
+ __Интерпретатор (Interpreter)__ - Решает часто встречающуюся, но подверженную изменениям, задачу.
+ __Итератор (Iterator)__ - это поведенческий паттерн проектирования, который даёт возможность последовательно обходить элементы составных объектов, не раскрывая их внутреннего представления (без использования описаний каждого + __из объектов, входящих в состав агрегации).
+ __Посредник (Mediator)__ - это поведенческий паттерн проектирования, который позволяет уменьшить связанность множества классов между собой, благодаря перемещению этих связей в один класс-посредник.
+ __Снимок (Memento)__ - это поведенческий паттерн проектирования, который позволяет сохранять и восстанавливать прошлые состояния объектов, не раскрывая подробностей их реализации.
+ __Наблюдатель (Observer)__ - это поведенческий паттерн проектирования, который создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах. Пример: ContexLoaderListener в Hibernate.
+ __Состояние (State)__ - Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния.
+ __Стратегия (Strategy)__ - это поведенческий паттерн проектирования, который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы.
+ __Шаблонный метод (Template method)__ - это поведенческий паттерн проектирования, который определяет скелет алгоритма, перекладывая ответственность за некоторые его шаги на подклассы. Паттерн позволяет подклассам переопределять шаги алгоритма, не меняя его общей структуры.
+ __Посетитель (Visitor)__ - это поведенческий паттерн проектирования, который позволяет добавлять в программу новые операции, не изменяя классы объектов, над которыми эти операции могут выполняться.
[к оглавлению](#Шаблоны-проектирования)
## Что такое антипаттерн»_? Какие антипаттерны вы знаете?
__Антипаттерн (anti-pattern)__ — это распространённый подход к решению класса часто встречающихся проблем, являющийся неэффективным, рискованным или непродуктивным.
__Poltergeists (полтергейсты)__ - это классы с ограниченной ответственностью и ролью в системе, чьё единственное предназначение — передавать информацию в другие классы. Их эффективный жизненный цикл непродолжителен. Полтергейсты нарушают стройность архитектуры программного обеспечения, создавая избыточные (лишние) абстракции, они чрезмерно запутанны, сложны для понимания и трудны в сопровождении. Обычно такие классы задумываются как классы-контроллеры, которые существуют только для вызова методов других классов, зачастую в предопределенной последовательности.
Признаки появления и последствия антипаттерна
+ Избыточные межклассовые связи.
+ Временные ассоциации.
+ Классы без состояния (содержащие только методы и константы).
+ Временные объекты и классы (с непродолжительным временем жизни).
+ Классы с единственным методом, который предназначен только для создания или вызова других классов посредством временной ассоциации.
+ Классы с именами методов в стиле «управления», такие как startProcess.
Типичные причины
+ Отсутствие объектно-ориентированной архитектуры (архитектор не понимает объектно-ориентированной парадигмы).
+ Неправильный выбор пути решения задачи.
+ Предположения об архитектуре приложения на этапе анализа требований (до объектно-ориентированного анализа) могут также вести к проблемам на подобии этого антипаттерна.
__Внесенная сложность (Introduced complexity)__: Необязательная сложность дизайна. Вместо одного простого класса выстраивается целая иерархия интерфейсов и классов. Типичный пример «Интерфейс - Абстрактный класс - Единственный класс реализующий интерфейс на основе абстрактного».
__Инверсия абстракции (Abstraction inversion)__: Сокрытие части функциональности от внешнего использования, в надежде на то, что никто не будет его использовать.
__Неопределённая точка зрения (Ambiguous viewpoint)__: Представление модели без спецификации её точки рассмотрения.
__Большой комок грязи (Big ball of mud)__: Система с нераспознаваемой структурой.
__Божественный объект (God object)__: Концентрация слишком большого количества функций в одной части системы (классе).
__Затычка на ввод данных (Input kludge)__: Забывчивость в спецификации и выполнении поддержки возможного неверного ввода.
__Раздувание интерфейса (Interface bloat)__: Разработка интерфейса очень мощным и очень сложным для реализации.
__Волшебная кнопка (Magic pushbutton)__: Выполнение результатов действий пользователя в виде неподходящего (недостаточно абстрактного) интерфейса. Например, написание прикладной логики в обработчиках нажатий на кнопку.
__Перестыковка (Re-Coupling)__: Процесс внедрения ненужной зависимости.
__Дымоход (Stovepipe System)__: Редко поддерживаемая сборка плохо связанных компонентов.
__Состояние гонки (Race hazard)__: непредвидение возможности наступления событий в порядке, отличном от ожидаемого.
__Членовредительство (Mutilation)__: Излишнее «затачивание» объекта под определенную очень узкую задачу таким образом, что он не способен будет работать с никакими иными, пусть и очень схожими задачами.
__Сохранение или смерть (Save or die)__: Сохранение изменений лишь при завершении приложения.
[к оглавлению](#Шаблоны-проектирования)
## Что такое _Dependency Injection_?
__Dependency Injection (внедрение зависимости)__ - это набор паттернов и принципов разработки програмного обеспечения, которые позволяют писать слабосвязный код. В полном соответствии с принципом единой обязанности объект отдаёт заботу о построении требуемых ему зависимостей внешнему, специально предназначенному для этого общему механизму.
[к оглавлению](#Шаблоны-проектирования)
# Источники
+ [Википедия](https://ru.wikipedia.org/wiki/Шаблон_проектирования)
+ [Javenue](http://www.javenue.info/post/56)
[Вопросы для собеседования](README.md)

@ -0,0 +1,235 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
1. Что такое RESTful API?
`RESTful API (Representational State Transfer)` - это стиль архитектуры веб-сервисов, который использует протокол HTTP для передачи данных между клиентом и сервером. RESTful API предоставляет ресурсы, такие как изображения, тексты или другие объекты, которые могут быть запрашиваемы клиентами с использованием уникального идентификатора URL.
Каждый ресурс может иметь несколько состояний (state), и клиент может изменять состояние ресурса, отправляя запросы на сервер с определенными методами HTTP, такими как GET, POST, PUT и DELETE.
RESTful API является популярным подходом для создания веб-сервисов, так как он облегчает построение расширяемых и масштабируемых приложений, позволяющих клиентам работать с данными и услугами, предоставляемыми сервером, без необходимости знать детали его внутренней реализации.
2. Какие методы HTTP используются в RESTful API?
В RESTful API используются следующие методы HTTP:
+ `GET` - используется для получения ресурса по указанному URL.
+ `POST` - используется для создания нового ресурса на сервере, часто с использованием данных, передаваемых в теле запроса.
+ `PUT` - используется для обновления существующего ресурса на сервере, часто с использованием данных, передаваемых в теле запроса.
+ `DELETE` - используется для удаления существующего ресурса на сервере.
+ `PATCH` - используется для частичного обновления существующего ресурса на сервере, часто с использованием данных, передаваемых в теле запроса.
+ `HEAD` - используется для получения метаданных о ресурсе, таких как заголовки, без получения самого ресурса.
+ `OPTIONS` - используется для получения информации о поддерживаемых методах HTTP для данного ресурса на сервере.
Каждый из этих методов имеет свое предназначение и используется для выполнения определенных операций над ресурсами, которые предоставляются через API.
3. Какие коды ответа HTTP вы можете использовать при создании RESTful API?
4. Какие типы контента поддерживаются в RESTful API?
5. Какой формат данных используется в RESTful API?
6. Какие библиотеки вы использовали для создания RESTful API?
7. Как вы обрабатываете ошибки в RESTful API?
8. Как вы обеспечиваете безопасность в RESTful API?
9. Как вы тестируете RESTful API?
10. Как вы улучшаете производительность RESTful API?
11. Как вы выполняете аутентификацию и авторизацию в RESTful API?
12. Как вы реализуете версионирование RESTful API?
13. Как вы обеспечиваете кэширование в RESTful API?
14. Как вы реализуете файловые загрузки в RESTful API?
15. Как вы реализуете запросы поиска в RESTful API?
16. Как вы реализуете пагинацию в RESTful API?
17. Как вы реализуете сортировку результатов в RESTful API?
18. Как вы обрабатываете транзакции в RESTful API?
19. Как вы реализуете обработку исключений в RESTful API?
20. Как вы обеспечиваете безопасность паролей в RESTful API?
21. Как вы реализуете асинхронную обработку запросов в RESTful API?
22. Как вы управляете жизненным циклом объектов в RESTful API?
23. Как вы реализуете аутентификацию с помощью JWT в RESTful API?
24. Как вы обрабатываете HTTP-запросы в RESTful API?
25. Как вы реализуете CORS в RESTful API?
26. Как вы тестируете микросервисы в RESTful API?
27. Как вы обеспечиваете сбор метрик в RESTful API?
28. Как вы используете Swagger для документирования RESTful API?
29. Как вы реализуете тестирование производительности RESTful API?
30. Как вы реализуете отказоустойчивость RESTful API?
31. Как вы реализуете асинхронные вызовы сервисов в RESTful API?
32. Как вы управляете версиями в RESTful API?
33. Как вы реализуете поддержку отображения данных в RESTful API?
34. Как вы управляете зависимостями в RESTful API?
35. Как вы обеспечиваете защиту от атак в RESTful API?
36. Как вы реализуете перевод ошибок RESTful API на разные языки?
37. Как вы используете Swagger для тестирования RESTful API?
38. Как вы реализуете механизм автоматической генерации документации RESTful API?
39. Как вы управляете конфигурацией RESTful API?
40. Как вы реализуете поддержку локализации в RESTful API?
41. Как вы реализуете аутентификацию с помощью OAuth в RESTful API?
42. Как вы реализуете кэширование запросов в RESTful API?
43. Как вы реализуете поддержку нескольких форматов ответа в RESTful API?
44. Как вы обеспечиваете защиту от DDOS-атак в RESTful API?
45. Как вы реализуете асинхронную передачу файлов в RESTful API?
46. Как вы управляете транзакциями при работе с несколькими ресурсами в RESTful API?
47. Как вы реализуете поддержку каскадного удаления в RESTful API?
48. Как вы реализуете ограничение доступа к определенным методам в RESTful API?
49. Как вы реализуете логирование действий в RESTful API?
50. Как вы обеспечиваете безопасность передачи данных между клиентом и сервером в RESTful API?
51. Как вы реализуете обработку ошибок в RESTful API?
52. Как вы реализуете отслеживание состояния запросов в RESTful API?
53. Как вы реализуете поддержку динамических параметров в RESTful API?
54. Как вы реализуете перехват вызовов методов в RESTful API?
55. Как вы использовали Hibernate для работы с базой данных в RESTful API?
56. Как вы реализуете поддержку множественных запросов в RESTful API?
57. Как вы используете Spring Security для обеспечения безопасности в RESTful API?
58. Как вы реализуете параллельную обработку запросов в RESTful API?
59. Как вы реализуете поддержку работы с календарными данными в RESTful API?
60. Как вы использовали JPA для работы с базой данных в RESTful API?
61. Как вы реализуете асинхронную обработку запросов с помощью CompletableFuture в RESTful API?
62. Как вы управляете зависимостями между сервисами в RESTful API?
63. Как вы используете Spring Boot для создания RESTful API?
64. Как вы реализуете поддержку работы с изображениями в RESTful API?
65. Как вы реализуете поддержку работы с геоданными в RESTful API?
66. Как вы обеспечиваете целостность и безопасность хранения паролей в RESTful API?
67. Как вы реализуете поддержку работы с датами и временем в RESTful API?
68. Как вы реализуете поддержку работы с XML в RESTful API?
69. Как вы управляете версионированием базы данных в RESTful API?
70. Как вы реализуете поддержку работы со списками и коллекциями в RESTful API?
71. Как вы реализуете поддержку работы с множественными языками в RESTful API?
72. Как вы обрабатываете большие объемы данных в RESTful API?
73. Как вы реализуете поддержку работы с файлами Excel в RESTful API?
74. Как вы реализуете поддержку множественных форматов документов в RESTful API?
75. Как вы обеспечиваете безопасность и защиту данных в RESTful API?
76. Как вы реализуете поддержку работы с аудио- и видеоданными в RESTful API?
77. Как вы реализуете поддержку работы с данными о местоположении в RESTful API?
78. Как вы реализуете поддержку работы с данными в формате JSON-Patch в RESTful API?
79. Как вы обеспечиваете защиту от SQL-инъекций в RESTful API?
80. Как вы реализуете поддержку работы с данными в формате HAL в RESTful API?
81. Как вы реализуете поддержку работы с данными в формате Siren в RESTful API?
82. Как вы реализуете поддержку работы с данными в формате Collection+JSON в RESTful API?
83. Как вы реализуете поддержку работы со связанными ресурсами в RESTful API?
84. Как вы реализуете поддержку работы со справочниками в RESTful API?
85. Как вы обеспечиваете безопасность передачи данных между сервисами в RESTful API?
86. Как вы реализуете поддержку работы с аннотациями в RESTful API?
87. Как вы реализуете поддержку работы с часовыми поясами в RESTful API?
88. Как вы реализуете поддержку работы с периодическими задачами в RESTful API?
89. Как вы реализуете поддержку работы с множественными форматами авторизации в RESTful API?
90. Как вы реализуете поддержку работы с хранилищами данных в памяти в RESTful API?
91. Как вы реализуете поддержку работы с различными типами запросов (GET, POST, PUT, DELETE) в RESTful API?
92. Как вы обеспечиваете защиту от CSRF-атак в RESTful API?
93. Как вы реализуете поддержку работы с несколькими форматами данных в RESTful API?
94. Как вы реализуете поддержку работы с данными в формате YAML в RESTful API?
95. Как вы реализуете поддержку работы с множественными форматами сериализации объектов в RESTful API?
96. Как вы реализуете поддержку работы с данными в формате MessagePack в RESTful API?
97. Как вы реализуете поддержку работы с данными в формате BSON в RESTful API?
98. Как вы обеспечиваете безопасность передачи данных между микросервисами в RESTful API?
99. Как вы реализуете поддержку работы с асинхронными запросами в RESTful API?
100. Как вы обеспечиваете защиту от нежелательного доступа к ресурсам в RESTful API?
101. Как вы управляете сессиями пользователей в RESTful API?
102. Как вы реализуете поддержку работы с документацией в RESTful API?
103. Как вы реализуете поддержку работы с параметрами языка в RESTful API?
104. Как вы реализуете поддержку работы с данными в формате Thrift в RESTful API?
105. Как вы реализуете поддержку работы с данными в формате Avro в RESTful API?
106. Как вы реализуете поддержку работы с данными в формате Protocol Buffers в RESTful API?
107. Как вы обеспечиваете защиту от переполнения буфера в RESTful API?
108. Как вы реализуете поддержку работы с несколькими языками программирования в RESTful API?
109. Как вы реализуете поддержку работы с данными в формате Ion в RESTful API?
110. Как вы реализуете поддержку работы с данными в формате CBOR в RESTful API?
111. Как вы работаете с многопоточностью в RESTful API?
112. Как вы реализуете поддержку работы с прокси-серверами в RESTful API?
113. Как вы реализуете поддержку работы с бинарными данными в RESTful API?
114. Как вы реализуете поддержку работы с графическими данными в RESTful API?
115. Как вы реализуете поддержку работы с данными в формате GraphQL в RESTful API?
116. Как вы обеспечиваете безопасность хранения данных в RESTful API?
117. Как вы обеспечиваете масштабируемость и отказоустойчивость RESTful API?
118. Как вы реализуете поддержку кэширования в RESTful API?
119. Как вы реализуете поддержку работы с данными в формате GeoJSON в RESTful API?
120. Как вы реализуете поддержку работы с данными о погоде в RESTful API?
121. Как вы обеспечиваете безопасность передачи данных через HTTPS в RESTful API?
122. Как вы реализуете поддержку работы с различными форматами кодирования данных в RESTful API?
123. Как вы реализуете поддержку работы с данными в формате RDF в RESTful API?
124. Как вы реализуете поддержку работы с данными в формате Turtle в RESTful API?
125. Как вы реализуете поддержку работы с данными в формате N-Triples в RESTful API?
126. Как вы реализуете поддержку работы с данными в формате N-Quads в RESTful API?
127. Как вы реализуете поддержку работы с данными в формате JSON-LD в RESTful API?
128. Как вы реализуете поддержку работы с данными в формате Microdata в RESTful API?
129. Как вы реализуете поддержку работы с данными в формате RDFa в RESTful API?
130. Как вы управляете версионированием API в RESTful API?
131. Как вы обеспечиваете безопасность при работе с личными данными пользователей в RESTful API?
132. Как вы реализуете поддержку работы с запросами в формате OData в RESTful API?
133. Как вы реализуете поддержку работы с данными в формате EDI в RESTful API?
134. Как вы реализуете автоматическое тестирование RESTful API?
135. Как вы обеспечиваете мониторинг и анализ производительности RESTful API?
136. Как вы реализуете поддержку работы с данными в формате PDF в RESTful API?
137. Как вы реализуете поддержку работы с данными в формате DocBook в RESTful API?
138. Как вы реализуете поддержку работы с данными в формате reStructuredText в RESTful API?
139. Как вы реализуете поддержку работы с данными в формате Markdown в RESTful API?
140. Как вы реализуете поддержку работы с данными в формате AsciiDoc в RESTful API?
141. Как вы реализуете поддержку работы с данными в формате CSV в RESTful API?
142. Как вы реализуете поддержку работы с данными в формате TSV в RESTful API?
143. Как вы реализуете поддержку работы с данными в формате XML Schema в RESTful API?
144. Как вы реализуете поддержку работы с данными в формате Relax NG в RESTful API?
145. Как вы реализуете поддержку работы с данными в формате XSL-FO в RESTful API?
146. Как вы обеспечиваете безопасность при работе с платежными системами в RESTful API?
147. Как вы реализуете мониторинг и логирование ошибок в RESTful API?
148. Как вы реализуете поддержку работы со структурированными данными в RESTful API?
149. Как вы реализуете поддержку работы с данными в формате XQuery в RESTful API?
150. Как вы обеспечиваете безопасность при работе с сетевыми протоколами в RESTful API?
151. Как вы реализуете поддержку работы с данными в формате XBRL в RESTful API?
152. Как вы реализуете поддержку работы с данными в формате RTF в RESTful API?
153. Как вы реализуете поддержку работы с данными в формате SVG в RESTful API?
154. Как вы реализуете поддержку работы с данными в формате PNG в RESTful API?
155. Как вы реализуете поддержку работы с данными в формате JPEG в RESTful API?
156. Как вы реализуете поддержку работы с данными в формате GIF в RESTful API?
157. Как вы реализуете поддержку работы с данными в формате BMP в RESTful API?
158. Как вы реализуете поддержку работы с данными в формате ICO в RESTful API?
159. Как вы реализуете поддержку работы с данными в формате TIFF в RESTful API?
160. Как вы реализуете поддержку работы с данными в формате PSD в RESTful API?
161. Как вы обеспечиваете защиту от инъекций кода в RESTful API?
162. Как вы реализуете поддержку работы с данными в формате DICOM в RESTful API?
163. Как вы реализуете поддержку работы с данными в формате HL7 в RESTful API?
164. Как вы реализуете поддержку работы с данными в формате FHIR в RESTful API?
165. Как вы реализуете поддержку работы с данными в формате CDA в RESTful API?
166. Как вы реализуете поддержку работы с данными в формате CCD в RESTful API?
167. Как вы реализуете поддержку работы с данными в формате HAPI в RESTful API?
168. Как вы реализуете поддержку работы с данными в формате SMART в RESTful API?
169. Как вы реализуете поддержку работы с данными в формате OAuth в RESTful API?
170. Как вы обеспечиваете защиту от утечек информации в RESTful API?
171. Как вы реализуете поддержку работы с данными в формате DICOMweb в RESTful API?
172. Как вы реализуете поддержку работы с данными в формате XACML в RESTful API?
173. Как вы реализуете поддержку работы с данными в формате SAML в RESTful API?
174. Как вы реализуете поддержку работы с данными в формате OpenID Connect в RESTful API?
175. Как вы реализуете поддержку работы с данными в формате JWT в RESTful API?
176. Как вы реализуете поддержку работы с данными в формате JOSE в RESTful API?
177. Как вы реализуете поддержку работы с данными в формате SCIM в RESTful API?
178. Как вы обеспечиваете защиту от DoS-атак в RESTful API?
179. Как вы реализуете поддержку работы с данными в формате OpenAPI в RESTful API?
180. Как вы обеспечиваете безопасность при работе с генетическими данными в RESTful API?
181. Как вы реализуете поддержку работы с данными в формате BAM в RESTful API?
182. Как вы реализуете поддержку работы с данными в формате VCF в RESTful API?
183. Как вы реализуете поддержку работы с данными в формате BED в RESTful API?
184. Как вы реализуете поддержку работы с данными в формате GTF/GFF в RESTful API?
185. Как вы реализуете поддержку работы с данными в формате SAM в RESTful API?
186. Как вы реализуете поддержку работы с данными в формате FASTA/FASTQ в RESTful API?
187. Как вы реализуете поддержку работы с данными в формате BCF в RESTful API?
188. Как вы реализуете поддержку работы с данными в формате WIG в RESTful API?
189. Как вы реализуете поддержку работы с данными в формате BigWig/BigBed в RESTful API?
190. Как вы обеспечиваете безопасность при работе с медицинскими данными в RESTful API?
191. Как вы реализуете поддержку работы с данными в формате DICOM SR в RESTful API?
192. Как вы реализуете поддержку работы с данными в формате PACS в RESTful API?
193. Как вы реализуете поддержку работы с данными в формате FHIR RESTful API?
194. Как вы реализуете поддержку работы с данными в формате DICOMweb RESTful API?
195. Как вы реализуете поддержку работы с данными в формате C-FIND/C-MOVE в RESTful API?
196. Как вы реализуете поддержку работы с данными в формате HL7v2 в RESTful API?
197. Как вы реализуете поддержку работы с данными в формате HL7v3 в RESTful API?
198. Как вы реализуете поддержку работы с данными в формате CCD/CDA в RESTful API?
199. Как вы реализуете поддержку работы с данными в формате IHE XDS/XDR в RESTful API?
200. Как вы обеспечиваете безопасность при работе с финансовыми данными в RESTful API?

@ -0,0 +1,919 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
Обычно порядок операций в SQL запросе следующий:
`SELECT`: выборка столбцов, которые будут отображаться в результирующей таблице.
`FROM`: указание источника данных (одной или нескольких таблиц) для выполнения запроса.
`WHERE`: определение условия, по которому будут отобраны строки из источника данных.
`GROUP BY`: группировка строк на основе значений одного или нескольких столбцов.
`HAVING`: определение условия, применяемого к группировке строк.
`ORDER BY`: упорядочивание строк в результате выполнения запроса по заданному столбцу или группе столбцов.
`LIMIT/OFFSET`: ограничение количества строк в результирующей таблице.
`Ключевые слова` - `Описание`
+ `ADD` Добавляет столбец в существующую таблицу
+ `ADD` CONSTRAINT Добавляет ограничение после того, как таблица уже создана
+ `ALTER` Добавляет, удаляет или изменяет столбцы в таблице, а также изменяет данные тип столбца в таблице
+ `ALTER COLUMN` Изменяет тип данных столбца в таблице
+ `ALTER TABLE` Добавляет, удаляет или изменяет столбцы в таблице
+ `ALL` Возвращает true, если все значения подзапроса соответствуют состояние
+ `AND` Включает только строки, где оба условия истинны
+ `ANY` Возвращает true, если какое-либо из значений подзапроса соответствует состоянию
+ `AS` Переименовывает столбец или таблицу с помощью псевдонима
+ `ASC` Сортировка результирующего набора в порядке возрастания
+ `BACKUP DATABASE` Создает резервную копию существующей базы данных
+ `BETWEEN` Выбор значений в заданном диапазоне
+ `CASE` Создает различные выходные данные в зависимости от условий
+ `CHECK` Ограничение, ограничивающее значение, которое может быть помещено в колонка
+ `COLUMN` Изменяет тип данных столбца или удаляет столбец в таблице
+ `CONSTRAINT` Добавляет или удаляет ограничение
+ `CREATE` Создает базу данных, индекс, представление, таблицу или процедуру
+ `CREATE DATABASE` Создает новую базу данных SQL
+ `CREATE INDEX` Создает индекс в таблице (позволяет дублировать значения)
+ `CREATE OR REPLACE VIEW` Обновление представления
+ `CREATE TABLE` Создает новую таблицу в базе данных
+ `CREATE PROCEDURE` Создает хранимую процедуру
+ `CREATE UNIQUE INDEX` Создает уникальный индекс в таблице (без повторяющихся значений)
+ `CREATE VIEW` Создает представление на основе результирующего набора инструкции SELECT
+ `DATABASE` Создает или удаляет базу данных SQL
+ `DEFAULT` Ограничение, предоставляющее значение по умолчанию для столбца
+ `DELETE` Удаляет строки из таблицы
+ `DESC` Сортировка результирующего набора в порядке убывания
+ `DISTINCT` Выбирает только отдельные (разные) значения
+ `DROP` Удаляет столбец, ограничение, базу данных, индекс, таблицу или представление
+ `DROP COLUMN` Удаляет столбец в таблице
+ `DROP CONSTRAINT` Удаляет UNIQUE, PRIMARY KEY, FOREIGN KEY, или ограничение CHECK
+ `DROP DATABASE` Удаляет существующую базу данных SQL
+ `DROP DEFAULT` Удаляет ограничение по умолчанию
+ `DROP INDEX` Удаление индекса в таблице
+ `DROP TABLE` Удаляет существующую таблицу в базе данных
+ `DROP VIEW` Удаление представления
+ `EXEC` Выполняет хранимую процедуру
+ `EXISTS` Тесты на наличие любой записи в подзапросе
+ `FOREIGN KEY` Ограничение, которое является ключом, используемым для связывания двух таблиц вместе
+ `FROM` Указывает, из какой таблицы следует выбрать или удалить данные
+ `FULL OUTER JOIN` Возвращает все строки при наличии совпадения в левой или правой таблице
+ `GROUP BY` Группирует результирующий набор (используется с агрегатными функциями: COUNT, MAX, MIN, SUM, AVG)
+ `HAVING` Используется вместо WHERE с агрегатными функциями
+ `IN Позволяет указать несколько значений в предложении WHERE
+ `INDEX` Создает или удаляет индекс в таблице
+ `INNER JOIN` Возвращает строки, имеющие совпадающие значения в обеих таблицах
+ `INSERT INTO` Вставка новых строк в таблицу
+ `INSERT INTO SELECT` Копирует данные из одной таблицы в другую
+ `IS NULL` Тесты для пустых значений
+ `IS NOT NULL` Тесты для непустых значений
+ `JOIN` Для объединения таблиц
+ `LEFT JOIN` Возвращает все строки из левой таблицы и соответствующие строки из правой таблицы
+ `LIKE` Поиск указанного шаблона в столбце
+ `LIMIT` Задает количество записей, возвращаемых в результирующем наборе
+ `NOT` Включает только строки, в которых условие не является истинным
+ `NOT NULL` Ограничение, которое заставляет столбец не принимать нулевые значения
+ `OR` Включает строки, в которых выполняется любое из условий
+ `ORDER BY` Сортировка результирующего набора в порядке возрастания или убывания
+ `OUTER JOIN` Возвращает все строки при наличии совпадения в левой или правой таблице
+ `PRIMARY KEY` Ограничение, которое однозначно идентифицирует каждую запись в таблице базы данных
+ `PROCEDURE` Хранимая процедура
+ `RIGHT JOIN` Возвращает все строки из правой таблицы и соответствующие строки из левой таблицы
+ `ROWNUM` Задает количество записей, возвращаемых в результирующем наборе
+ `SELECT` Выбор данных из базы данных
+ `SELECT DISTINCT` Выбирает только отдельные (разные) значения
+ `SELECT INTO` Копирует данные из одной таблицы в новую таблицу
+ `SELECT TOP` Задает количество записей, возвращаемых в результирующем наборе
+ `SET` Указывает, какие столбцы и значения должны быть обновлены в таблице
+ `TABLE` Создает таблицу, добавляет, удаляет или изменяет столбцы в таблице, а также удаляет таблицу или данные внутри таблицы
+ `TOP` Задает количество записей, возвращаемых в результирующем наборе
+ `TRUNCATE TABLE` Удаляет данные внутри таблицы, но не саму таблицу
+ `UNION` Объединяет результирующий набор из двух или более операторов SELECT (только отдельные значения)
+ `UNION ALL` Объединяет результирующий набор из двух или более операторов SELECT (позволяет дублировать значения)
+ `UNIQUE` Ограничение, обеспечивающее уникальность всех значений в столбце
+ `UPDATE` Обновление существующих строк в таблице
+ `VALUES` Задает значения инструкции INSERT INTO
+ `VIEW` Создает, обновляет или удаляет представление
+ `WHERE` Фильтрует результирующий набор для включения только тех записей, которые удовлетворяют заданному условию
1. Что такое SQL?
2. Какой реляционный базовый язык используется в SQL?
3. Для чего необходимо использование SQL?
4. Какие преимущества имеет SQL перед другими реляционными базами данных?
5. Какие типы данных поддерживает SQL?
6. Что такое транзакция?
7. Что такое оператор SELECT?
8. Что такое WHERE?
9. Что такое ORDER BY?
10. Что такое GROUP BY?
11. Что такое HAVING?
12. Что такое JOIN?
13. Какие виды JOIN бывают в SQL?
14. Что такое INNER JOIN?
15. Что такое LEFT JOIN?
16. Что такое RIGHT JOIN?
17. Что такое FULL OUTER JOIN?
18. Что такое SELF JOIN?
19. Что такое UNION и UNION ALL?
20. Что такое SUBQUERY?
21. Что такое коррелирующий запрос?
22. Что такое представления (view)?
23. Каковы основные принципы проектирования базы данных?
24. Что такое нормализация?
25. Какие виды нормализации бывают в SQL?
26. Что такое индекс и какие виды индексов существуют?
27. Какой вид индекса использовать для какого типа запросов?
28. Как сделать определенное поле уникальным?
29. Что такое триггеры?
30. Как создать триггер в SQL?
31. Что такое ограничения (constraints) и какие они бывают?
32. Как создать таблицу с ограничениями?
33. Как изменить ограничения на существующей таблице?
34. Что такое хранимая процедура и как ее создать?
35. Что такое функция и как ее создать?
36. Какие функции поддерживает SQL?
37. Как работать с датами в SQL?
38. Что такое оператор CASE?
39. Что такое оператор COALESCE?
40. Что такое оператор LIKE?
41. Какие операторы сравнения поддерживает SQL?
42. Что такое агрегатные функции и какие они бывают?
43. Как работать с NULL-значениями в SQL?
44. Что такое инструкция TRUNCATE?
45. В чем разница между инструкцией DELETE и TRUNCATE?
46. Что такое ключевое слово DISTINCT?
47. Что такое ключевое слово LIMIT?
48. Что такое ключевое слово OFFSET?
49. Что такое ключевое слово TOP?
50. Что такое GROUP_CONCAT?
51. Что такое аналитические функции?
52. Какие аналитические функции поддерживает SQL?
53. Как использовать операторы BETWEEN и IN в SQL?
54. Что такое инструкция INSERT?
55. Какие виды инструкции INSERT бывают в SQL?
56. Что такое инструкция UPDATE?
57. Как работать с несколькими таблицами в одном запросе?
58. Как сделать выборку из таблицы по определенному диапазону значений?
59. Как работать с динамическими запросами в SQL?
60. Как произвести создание и удаление таблиц в SQL?
61. Какие виды ограничений можно использовать в SQL?
62. Как работать с индексами в SQL
63. Какие индексы могут быть использованы в SQL?
64. Что такое кластеризованный и некластеризованный индекс?
65. Какие операторы логических связок (AND, OR, NOT) существуют в SQL?
66. Что такое подзапросы и как они работают в SQL?
67. Как использовать операторы LIKE и NOT LIKE в SQL?
68. Какие виды функций агрегации существуют в SQL?
69. Что такое LEFT OUTER JOIN и RIGHT OUTER JOIN?
70. Как использовать ключевое слово DISTINCT для удаления дубликатов в SQL?
71. Как использовать операторы IN и NOT IN в SQL?
72. Что такое оконные функции и как они работают в SQL?
73. Как создать таблицу с помощью команды CREATE TABLE в SQL?
74. Как изменить структуру таблицы с помощью команды ALTER TABLE в SQL?
75. Как удалить таблицу с помощью команды DROP TABLE в SQL?
76. Как использовать операторы IS NULL и IS NOT NULL в SQL?
77. Что такое агрегатная функция SUM() и как она используется в SQL?
78. Как использовать операторы GROUP BY и HAVING в SQL?
79. Как использовать операторы ORDER BY и LIMIT в SQL?
80. Как сделать выборку строк из таблицы с помощью оператора SELECT в SQL?
81. Как использовать операторы BETWEEN и NOT BETWEEN в SQL?
82. Как работать с датами и временем в SQL?
83. Как создать индекс на одном или нескольких столбцах в SQL?
84. Что такое функция COUNT() и как она используется в SQL?
85. Как использовать оператор LIKE для поиска определенных значений в SQL?
86. Какие виды данных можно хранить в SQL?
87. Как использовать операторы AND и OR в SQL?
88. Как использовать ключевое слово LEFT JOIN в SQL?
89. Как использовать ключевое слово RIGHT JOIN в SQL?
90. Что такое таблица соединения и как она используется в SQL?
91. Как использовать оператор DISTINCT в SQL?
92. Что такое функция MAX() и как она используется в SQL?
93. Как использовать оператор UNION в SQL?
94. Что такое функция MIN() и как она используется в SQL?
95. Как использовать операторы IN и EXISTS в SQL?
96. Как использовать операторы LIKE и IN в SQL?
97. Что такое операторы ALL и ANY в SQL?
98. Как использовать операторы EXISTS и NOT EXISTS в SQL?
99. Как использовать операторы CASE и WHEN в SQL?
100. Как использовать операторы SELECT и INSERT в SQL?
101. Что такое RDBMS?
102. Какие типы данных поддерживает SQL?
103. Что такое таблица в SQL?
104. Как создать таблицу в SQL?
105. Как изменить таблицу в SQL?
106. Что такое ключевое поле (primary key) и как его использовать?
107. Что такое внешний ключ (foreign key) и как его использовать?
108. Что такое индекс и как его использовать?
109. Что такое транзакция и зачем она нужна?
110. Что такое COMMIT и ROLLBACK?
111. Что такое представление (view) и как его использовать?
112. Что такое процедура (stored procedure)?
113. Как создать процедуру в SQL?
114. Как вызвать процедуру в SQL?
115. Что такое функция (stored function) и как ее использовать?
116. Как создать функцию в SQL?
117. Как вызвать функцию в SQL?
118. Какие типы JOIN используются в SQL?
119. Что такое INNER JOIN?
120. Что такое LEFT JOIN?
121. Что такое RIGHT JOIN?
122. Что такое FULL OUTER JOIN?
123. Как использовать подзапрос (subquery) в SQL?
124. Какие виды операторов SELECT используются в SQL?
125. Что такое оператор DISTINCT и как его использовать?
126. Что такое оператор WHERE и как его использовать?
127. Что такое оператор GROUP BY и как его использовать?
128. Что такое оператор HAVING и как его использовать?
129. Что такое оператор ORDER BY и как его использовать?
130. Какие функции агрегации используются в SQL?
131. Что такое AVG и как его использовать?
132. Что такое SUM и как его использовать?
133. Что такое COUNT и как его использовать?
134. Что такое MAX и как его использовать?
135. Что такое MIN и как его использовать?
136. Как использовать условные операторы (CASE, IF) в SQL?
137. Что такое триггер (trigger) и как его использовать?
138. Как создать триггер в SQL?
139. Как удалить триггер в SQL?
140. Что такое индексы и как их использовать?
141. Что такое кластерный индекс (clustered index)?
142. Что такое некластерный индекс (non-clustered index)?
143. Какие виды баз данных бывают?
144. Что такое NoSQL?
145. Какие базы данных относятся к NoSQL?
146. Что такое MongoDB?
147. Что такое Redis?
148. Что такое Cassandra?
149. Что такое Couchbase?
150. Что такое HBase?
151. Что такое Neo4j?
152. Что такое Riak?
153. Что такое DynamoDB?
154. Как использовать MongoDB в Java-приложении?
155. Как использовать Redis в Java-приложении?
156. Как использовать Cassandra в Java-приложении?
157. Как использовать Couchbase в Java-приложении?
158. Как использовать HBase в Java-приложении?
159. Как использовать Neo4j в Java-приложении?
160. Как использовать Riak в Java-приложении?
161. Как использовать DynamoDB в Java-приложении?
162. Что такое ORM и какие библиотеки ORM для Java вы знаете?
163. Что такое Hibernate?
164. Как использовать Hibernate в Java-приложении?
165. Что такое JPA?
166. Как использовать JPA в Java-приложении?
68. Что такое JDBC?
69. Как использовать JDBC в Java-приложении?
70. Что такое Spring Data?
71. Как использовать Spring Data в Java-приложении?
72. Что такое MyBatis?
73. Как использовать MyBatis в Java-приложении?
74. Что такое Apache Camel?
75. Как использовать Apache Camel в Java-приложении?
76. Что такое ETL процесс?
77. Как реализовать ETL процесс с помощью Java?
78. Как улучшить производительность SQL запросов?
79. Как оптимизировать SQL запросы?
80. Как ускорить выполнение SQL запросов?
81. Что такое индексация в базах данных?
82. Как создать индексы в базе данных?
83. Как удалить индексы из базы данных?
84. Какие типы индексов бывают?
85. Что такое B-Tree индекс?
86. Что такое Hash индекс?
87. Что такое Bitmap индекс?
88. Что такое функциональный индекс?
89. Как работает оптимизатор запросов в базах данных?
90. Как узнать план выполнения запроса в базе данных?
91. Что такое deadlock и как его избежать?
92. Что такое SQL injection и как его предотвратить?
93. Как сделать backup базы данных?
94. Что такое резервное копирование?
95. Как восстановить базу данных из backup?
96. Что такое log shipping?
97. Как использовать log shipping для репликации базы данных?
98. Что такое многопоточность в базах данных?
99. Какие проблемы могут возникнуть при использовании многопоточности в базах данных?
100. Как решить проблемы с многопоточностью в базах данных?
101. Что такое репликация базы данных?
102. Как настроить репликацию базы данных?
103. Что такое масштабирование базы данных?
104. Как настроить масштабирование базы данных?
105. Что такое шардинг?
106. Как настроить шардинг в базе данных?
107. Что такое горизонтальный шардинг?
108. Что такое вертикальный шардинг?
109. Какой подход лучше для шардинга?
110. Что такое партиционирование таблицы?
111. Как настроить партиционирование таблицы?
112. Что такое отказоустойчивость базы данных?
113. Как обеспечить отказоустойчивость базы данных?
114. Что такое резервный сервер базы данных?
115. Как использовать резервный сервер базы данных?
116. Что такое кластер базы данных?
117. Как настроить кластер базы данных?
118. Что такое мониторинг базы данных?
119. Как настроить мониторинг базы данных?
120. Какие инструменты мониторинга базы данных вы знаете?
121. Что такое профилирование SQL запросов?
122. Как настроить профилирование SQL запросов?
123. Какие инструменты профилирования SQL запросов вы знаете?
124. Что такое миграции базы данных?
125. Как настроить миграции базы данных?
126. Какие инструменты миграции базы данных вы знаете?
127. Что такое архитектура базы данных?
128. Какие паттерны проектирования используются при проектировании базы данных?
129. Какие принципы SOLID применяются при разработке базы данных?
130. Что такое ER-модель?
131. Как использовать ER-модель для проектирования базы данных?
132. Что такое UML и как его использовать при проектировании базы данных?
133. Что такое «SQL»?
134. Какие существуют операторы SQL?
135. Что означает NULL в SQL?
136. Что такое «временная таблица»? Для чего она используется?
137. Что такое «представление» (view) и для чего оно применяется?
138. Каков общий синтаксис оператора SELECT?
139. Что такое JOIN?
140. Какие существуют типы JOIN?
141. Что лучше использовать JOIN или подзапросы?
142. Для чего используется оператор HAVING?
143. В чем различие между операторами HAVING и WHERE?
144. Для чего используется оператор ORDER BY?
145. Для чего используется оператор GROUP BY?
146. Как GROUP BY обрабатывает значение NULL?
147. В чем разница между операторами GROUP BY и DISTINCT?
148. Перечислите основные агрегатные функции.
149. В чем разница между COUNT(*) и COUNT({column})?
150. Что делает оператор EXISTS?
151. Для чего используются операторы IN, BETWEEN, LIKE?
152. Для чего применяется ключевое слово UNION?
153. Какие ограничения на целостность данных существуют в SQL?
154. Какие отличия между ограничениями PRIMARY и UNIQUE?
155. Может ли значение в столбце, на который наложено ограничение FOREIGN KEY, равняться NULL?
156. Как создать индекс?
157. Что делает оператор MERGE?
158. В чем отличие между операторами DELETE и TRUNCATE?
159. Что такое «хранимая процедура»?
160. Что такое «триггер»?
161. Что такое «курсор»?
162. Опишите разницу типов данных DATETIME и TIMESTAMP.
163. Для каких числовых типов недопустимо использовать операции сложения/вычитания?
164. Какое назначение у операторов PIVOT и UNPIVOT в Transact-SQL?
165. Расскажите об основных функциях ранжирования в Transact-SQL.
166. Для чего используются операторы INTERSECT, EXCEPT в Transact-SQL?
# SQL
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [SQL](#sql)
- [Что такое _«SQL»_?](#что-такое-sql)
- [Какие существуют операторы SQL?](#какие-существуют-операторы-sql)
- [Что означает `NULL` в SQL?](#что-означает-null-в-sql)
- [Что такое _«временная таблица»_? Для чего она используется?](#что-такое-временная-таблица-для-чего-она-используется)
- [Что такое _«представление» (view)_ и для чего оно применяется?](#что-такое-представление-view-и-для-чего-оно-применяется)
- [Каков общий синтаксис оператора `SELECT`?](#каков-общий-синтаксис-оператора-select)
- [Что такое `JOIN`?](#что-такое-join)
- [Какие существуют типы `JOIN`?](#какие-существуют-типы-join)
- [Что лучше использовать `JOIN` или подзапросы?](#что-лучше-использовать-join-или-подзапросы)
- [Для чего используется оператор `HAVING`?](#для-чего-используется-оператор-having)
- [В чем различие между операторами `HAVING` и `WHERE`?](#в-чем-различие-между-операторами-having-и-where)
- [Для чего используется оператор `ORDER BY`?](#для-чего-используется-оператор-order-by)
- [Для чего используется оператор `GROUP BY`?](#для-чего-используется-оператор-group-by)
- [Как `GROUP BY` обрабатывает значение `NULL`?](#как-group-by-обрабатывает-значение-null)
- [В чем разница между операторами `GROUP BY` и `DISTINCT`?](#в-чем-разница-между-операторами-group-by-и-distinct)
- [Перечислите основные агрегатные функции.](#перечислите-основные-агрегатные-функции)
- [В чем разница между `COUNT(*)` и `COUNT({column})`?](#в-чем-разница-между-count-и-countcolumn)
- [Что делает оператор `EXISTS`?](#что-делает-оператор-exists)
- [Для чего используются операторы `IN`, `BETWEEN`, `LIKE`?](#для-чего-используются-операторы-in-between-like)
- [Для чего применяется ключевое слово `UNION`?](#для-чего-применяется-ключевое-слово-union)
- [Какие ограничения на целостность данных существуют в SQL?](#какие-ограничения-на-целостность-данных-существуют-в-sql)
- [Какие отличия между ограничениями `PRIMARY` и `UNIQUE`?](#какие-отличия-между-ограничениями-primary-и-unique)
- [Может ли значение в столбце, на который наложено ограничение `FOREIGN KEY`, равняться `NULL`?](#может-ли-значение-в-столбце-на-который-наложено-ограничение-foreign-key-равняться-null)
- [Как создать индекс?](#как-создать-индекс)
- [Что делает оператор `MERGE`?](#что-делает-оператор-merge)
- [В чем отличие между операторами `DELETE` и `TRUNCATE`?](#в-чем-отличие-между-операторами-delete-и-truncate)
- [Что делает оператор `EXPLAIN`?](#что-делает-оператор-explain)
- [Что такое _«RETURNING»_?](#что-такое-returning)
- [Что такое _«хранимая процедура»_?](#что-такое-хранимая-процедура)
- [Что такое _«триггер»_?](#что-такое-триггер)
- [Что такое _«курсор»_?](#что-такое-курсор)
- [Опишите разницу типов данных `DATETIME` и `TIMESTAMP`.](#опишите-разницу-типов-данных-datetime-и-timestamp)
- [Для каких числовых типов недопустимо использовать операции сложения/вычитания?](#для-каких-числовых-типов-недопустимо-использовать-операции-сложениявычитания)
- [Какое назначение у операторов `PIVOT` и `UNPIVOT` в Transact-SQL?](#какое-назначение-у-операторов-pivot-и-unpivot-в-transact-sql)
- [Расскажите об основных функциях ранжирования в Transact-SQL.](#расскажите-об-основных-функциях-ранжирования-в-transact-sql)
- [Для чего используются операторы `INTERSECT`, `EXCEPT` в Transact-SQL?](#для-чего-используются-операторы-intersect-except-в-transact-sql)
- [Напишите запрос...](#напишите-запрос)
- [Источники](#источники)
## Что такое _«SQL»_?
SQL, Structured query language («язык структурированных запросов») — формальный непроцедурный язык программирования, применяемый для создания, модификации и управления данными в произвольной реляционной базе данных, управляемой соответствующей системой управления базами данных (СУБД).
Формальный - множество конечных слов (строк, цепочек) над конечным алфавитом. Различают языки естественные, на которых общаются люди, и искусственные (или формальные).
Непроцедурный - каждый оператор выдает результат, соответствующий запрашиваемому выходу. Ответственность за то, как добиться соответствующего выхода, лежит, в значительной степени, на моторе (движке) базы данных.
[к оглавлению](#sql)
## Какие существуют операторы SQL?
__операторы определения данных (Data Definition Language, DDL)__:
+ `CREATE` создает объект БД (базу, таблицу, представление, пользователя и т. д.),
+ `ALTER` изменяет объект,
+ `DROP` удаляет объект,
+ `TRUNCATE` - удаляет таблицу и создает ее заново. Причем если на эту таблицу есть ссылки `FOREGIN KEY` или таблица используется в репликации, то пересоздать такую таблицу не получится.
+ `RENAME` переименовыывает объект;
__операторы манипуляции данными (Data Manipulation Language, DML)__:
+ `SELECT` выбирает данные, удовлетворяющие заданным условиям,
+ `INSERT` добавляет новые данные,
+ `UPDATE` изменяет существующие данные,
+ `DELETE` удаляет данные;
__операторы определения доступа к данным (Data Control Language, DCL)__:
+ `GRANT` предоставляет пользователю (группе) разрешения на определенные операции с объектом,
+ `REVOKE` отзывает ранее выданные разрешения,
+ `DENY` задает запрет, имеющий приоритет над разрешением;
__операторы управления транзакциями (Transaction Control Language, TCL)__:
+ `COMMIT` применяет транзакцию,
+ `ROLLBACK` откатывает все изменения, сделанные в контексте текущей транзакции,
+ `SAVEPOINT` разбивает транзакцию на более мелкие.
[к оглавлению](#sql)
## Что означает `NULL` в SQL?
`NULL` - специальное значение (псевдозначение), которое может быть записано в поле таблицы базы данных. NULL соответствует понятию «пустое поле», то есть «поле, не содержащее никакого значения».
`NULL` означает отсутствие, неизвестность информации. Значение `NULL` не является значением в полном смысле слова: по определению оно означает отсутствие значения и не принадлежит ни одному типу данных. Поэтому `NULL` не равно ни логическому значению `FALSE`, ни _пустой строке_, ни `0`. При сравнении `NULL` с любым значением будет получен результат `NULL`, а не `FALSE` и не `0`. Более того, `NULL` не равно `NULL`!
[к оглавлению](#sql)
## Что такое _«временная таблица»_? Для чего она используется?
__Временная таблица__ - это объект базы данных, который хранится и управляется системой базы данных на временной основе. Они могут быть локальными или глобальными. Используется для сохранения результатов вызова хранимой процедуры, уменьшение числа строк при соединениях, агрегирование данных из различных источников или как замена курсоров и параметризованных представлений.
[к оглавлению](#sql)
## Что такое _«представление» (view)_ и для чего оно применяется?
__Представление__, View - виртуальная таблица, представляющая данные одной или более таблиц альтернативным образом. Представления широко используются когда необходимо представить структуру базы данных в удобном для восприятия человеком виде, а так же в соображениях безопасности, предоставляя пользователям возможность обращаться к данным, но не разрешая им доступ к исходным таблицам.
В действительности представление всего лишь результат выполнения оператора `SELECT`, который хранится в структуре памяти, напоминающей SQL таблицу. Они работают в запросах и операторах DML точно также как и основные таблицы, но не содержат никаких собственных данных. Представления значительно расширяют возможности управления данными. Это способ дать публичный доступ к некоторой (но не всей) информации в таблице.
Для создания представления используется оператор SQL CREATE и синтаксис выглядит следующим образом:
```java
CREATE VIEW view_name
AS SELECT column_name
FROM table_name
WHERE condition
```
[к оглавлению](#sql)
## Каков общий синтаксис оператора `SELECT`?
`SELECT` - оператор DML SQL, возвращающий набор данных (выборку) из базы данных, удовлетворяющих заданному условию. Имеет следующую структуру:
```sql
SELECT
[DISTINCT | DISTINCTROW | ALL]
select_expression,...
FROM table_references
[WHERE where_definition]
[GROUP BY {unsigned_integer | column | formula}]
[HAVING where_definition]
[ORDER BY {unsigned_integer | column | formula} [ASC | DESC], ...]
```
[к оглавлению](#sql)
## Что такое `JOIN`?
__JOIN__ - оператор языка SQL, который является реализацией операции соединения реляционной алгебры. Предназначен для обеспечения выборки данных из двух таблиц и включения этих данных в один результирующий набор.
Особенностями операции соединения являются следующее:
+ в схему таблицы-результата входят столбцы обеих исходных таблиц (таблиц-операндов), то есть схема результата является «сцеплением» схем операндов;
+ каждая строка таблицы-результата является «сцеплением» строки из одной таблицы-операнда со строкой второй таблицы-операнда;
+ при необходимости соединения не двух, а нескольких таблиц, операция соединения применяется несколько раз (последовательно).
```sql
SELECT
field_name [,... n]
FROM
Table1
{INNER | {LEFT | RIGHT | FULL} OUTER | CROSS } JOIN
Table2
{ON <condition> | USING (field_name [,... n])}
```
[к оглавлению](#sql)
## Какие существуют типы `JOIN`?
__(INNER) JOIN__
Результатом объединения таблиц являются записи, общие для левой и правой таблиц. Порядок таблиц для оператора не важен, поскольку оператор является симметричным.
__LEFT (OUTER) JOIN__
Производит выбор всех записей первой таблицы и соответствующих им записей второй таблицы. Если записи во второй таблице не найдены, то вместо них подставляется пустой результат (`NULL`). Порядок таблиц для оператора важен, поскольку оператор не является симметричным.
__RIGHT (OUTER) JOIN__
`LEFT JOIN` с операндами, расставленными в обратном порядке. Порядок таблиц для оператора важен, поскольку оператор не является симметричным.
__FULL (OUTER) JOIN__
Результатом объединения таблиц являются все записи, которые присутствуют в таблицах. Порядок таблиц для оператора не важен, поскольку оператор является симметричным.
__CROSS JOIN (декартово произведение)__
При выборе каждая строка одной таблицы объединяется с каждой строкой второй таблицы, давая тем самым все возможные сочетания строк двух таблиц. Порядок таблиц для оператора не важен, поскольку оператор является симметричным.
[к оглавлению](#sql)
## Что лучше использовать `JOIN` или подзапросы?
Обычно лучше использовать `JOIN`, поскольку в большинстве случаев он более понятен и лучше оптимизируется СУБД (но 100% этого гарантировать нельзя). Так же `JOIN` имеет заметное преимущество над подзапросами в случае, когда список выбора `SELECT` содержит столбцы более чем из одной таблицы.
Подзапросы лучше использовать в случаях, когда нужно вычислять агрегатные значения и использовать их для сравнений во внешних запросах.
[к оглавлению](#sql)
## Для чего используется оператор `HAVING`?
`HAVING` используется для фильтрации результата `GROUP BY` по заданным логическим условиям.
[к оглавлению](#sql)
## В чем различие между операторами `HAVING` и `WHERE`?
`WHERE` - это ограничивающее выражение. Оно выполняется до того, как будет получен результат операции. WHERE служит для задания дополнительного условия выборки, операций вставки, редактирования и удаления записей. Условие (condition) может включать в себя предикаты AND, OR, NOT, LIKE, BETWEEN, IS, IN, ключевое слово NULL, операторы сравнения и равенства (<, >, =).
```java
SELECT * FROM Planets WHERE Radius BETWEEN 3000 AND 9000
```
`HAVING` - Оператор SQL HAVING является указателем на результат выполнения агрегатных функций. Агрегатной функцией в языке SQL называется функция, возвращающая какое-либо одно значение по набору значений столбца. Такими функциями являются: SQL COUNT(), SQL MIN(), SQL MAX(), SQL AVG(), SQL SUM().
```java
SELECT Singer, SUM(Sale)
FROM Artists
GROUP BY Singer
HAVING SUM(Sale) > 2000000
```
Выражения WHERE используются вместе с операциями SELECT, UPDATE, DELETE, в то время как HAVING только с SELECT и предложением GROUP BY.
[к оглавлению](#sql)
## Для чего используется оператор `ORDER BY`?
__ORDER BY__ упорядочивает вывод запроса согласно значениям в том или ином количестве выбранных столбцов. Многочисленные столбцы упорядочиваются один внутри другого. Возможно определять возрастание `ASC` или убывание `DESC` для каждого столбца. По умолчанию установлено - возрастание.
[к оглавлению](#sql)
## Для чего используется оператор `GROUP BY`?
`GROUP BY` используется для агрегации записей результата по заданному столбцу.
[к оглавлению](#sql)
## Как `GROUP BY` обрабатывает значение `NULL`?
При использовании `GROUP BY` все значения `NULL` считаются равными.
[к оглавлению](#sql)
## В чем разница между операторами `GROUP BY` и `DISTINCT`?
`DISTINCT` указывает, что для вычислений используются только уникальные значения столбца. `NULL` считается как отдельное значение. DISTINCT нашел широкое применение в операторе SQL SELECT, для выборки уникальных значений. Так же используется в агрегатных функциях.
```java
SELECT DISTINCT column_name FROM table_name
```
`GROUP BY` используется для объединения результатов выборки по одному или нескольким столбцам. создает отдельную группу для всех возможных значений (включая значение `NULL`).
Если нужно удалить только дубликаты лучше использовать `DISTINCT`, `GROUP BY` лучше использовать для определения групп записей, к которым могут применяться агрегатные функции.
[к оглавлению](#sql)
## Перечислите основные агрегатные функции.
__Агрегатных функции__ - функции, которые берут группы значений и сводят их к одиночному значению.
SQL предоставляет несколько агрегатных функций:
`COUNT` - производит подсчет записей, удовлетворяющих условию запроса;
`SUM` - вычисляет арифметическую сумму всех значений колонки;
`AVG` - вычисляет среднее арифметическое всех значений;
`MAX` - определяет наибольшее из всех выбранных значений;
`MIN` - определяет наименьшее из всех выбранных значений.
[к оглавлению](#sql)
## В чем разница между `COUNT(*)` и `COUNT({column})`?
`COUNT (*)` подсчитывает количество записей в таблице, не игнорируя значение NULL, поскольку эта функция оперирует записями, а не столбцами.
`COUNT ({column})` подсчитывает количество значений в `{column}`. При подсчете количества значений столбца эта форма функции `COUNT` не принимает во внимание значение `NULL`.
[к оглавлению](#sql)
## Что делает оператор `EXISTS`?
`EXISTS` берет подзапрос, как аргумент, и оценивает его как `TRUE`, если подзапрос возвращает какие-либо записи и `FALSE`, если нет.
[к оглавлению](#sql)
## Для чего используются операторы `IN`, `BETWEEN`, `LIKE`?
`IN` - определяет набор значений.
```sql
SELECT * FROM Persons WHERE name IN ('Ivan','Petr','Pavel');
```
`BETWEEN` определяет диапазон значений. В отличие от `IN`, `BETWEEN` чувствителен к порядку, и первое значение в предложении должно быть первым по алфавитному или числовому порядку.
```sql
SELECT * FROM Persons WHERE age BETWEEN 20 AND 25;
```
`LIKE` применим только к полям типа `CHAR` или `VARCHAR`, с которыми он используется чтобы находить подстроки. В качестве условия используются _символы шаблонизации (wildkards_) - специальные символы, которые могут соответствовать чему-нибудь:
+ `_` замещает любой одиночный символ. Например, `'b_t'` будет соответствовать словам `'bat'` или `'bit'`, но не будет соответствовать `'brat'`.
+ `%` замещает последовательность любого числа символов. Например `'%p%t'` будет соответствовать словам `'put'`, `'posit'`, или `'opt'`, но не `'spite'`.
```sql
SELECT * FROM UNIVERSITY WHERE NAME LIKE '%o';
```
[к оглавлению](#sql)
## Для чего применяется ключевое слово `UNION`?
В языке SQL ключевое слово `UNION` применяется для объединения результатов двух SQL-запросов в единую таблицу, состоящую из схожих записей. Оба запроса должны возвращать одинаковое число столбцов и совместимые типы данных в соответствующих столбцах. Необходимо отметить, что `UNION` сам по себе не гарантирует порядок записей. Записи из второго запроса могут оказаться в начале, в конце или вообще перемешаться с записями из первого запроса. В случаях, когда требуется определенный порядок, необходимо использовать `ORDER BY`.
С удалением дублей:
```sql
SELECT * FROM имя_таблицы1 WHERE условие
UNION SELECT * FROM имя_таблицы2 WHERE условие
```
Без удаления дублей:
```sql
SELECT * FROM имя_таблицы1 WHERE условие
UNION ALL SELECT * FROM имя_таблицы2 WHERE условие
```
Можно объединять не две таблицы, а три или более:
```sql
SELECT * FROM имя_таблицы1 WHERE условие
UNION SELECT * FROM имя_таблицы2 WHERE условие
UNION SELECT * FROM имя_таблицы3 WHERE условие
UNION SELECT * FROM имя_таблицы4 WHERE услови
```
[к оглавлению](#sql)
## Какие ограничения на целостность данных существуют в SQL?
__sql constraint__
`PRIMARY KEY` - набор полей (1 или более), значения которых образуют уникальную комбинацию и используются для однозначной идентификации записи в таблице. Для таблицы может быть создано только одно такое ограничение. Данное ограничение используется для обеспечения целостности сущности, которая описана таблицей.
`CHECK` используется для ограничения множества значений, которые могут быть помещены в данный столбец. Это ограничение используется для обеспечения целостности предметной области, которую описывают таблицы в базе.
`UNIQUE` обеспечивает отсутствие дубликатов в столбце или наборе столбцов.
`FOREIGN KEY` защищает от действий, которые могут нарушить связи между таблицами. `FOREIGN KEY` в одной таблице указывает на `PRIMARY KEY` в другой. Поэтому данное ограничение нацелено на то, чтобы не было записей `FOREIGN KEY`, которым не отвечают записи `PRIMARY KEY`.
[к оглавлению](#sql)
## Какие отличия между ограничениями `PRIMARY` и `UNIQUE`?
По умолчанию ограничение `PRIMARY` создает кластерный индекс на столбце, а `UNIQUE` - некластерный. Другим отличием является то, что `PRIMARY` не разрешает `NULL` записей, в то время как `UNIQUE` разрешает одну (а в некоторых СУБД несколько) `NULL` запись.
[к оглавлению](#sql)
## Может ли значение в столбце, на который наложено ограничение `FOREIGN KEY`, равняться `NULL`?
Может, если на данный столбец не наложено ограничение `NOT NULL`.
[к оглавлению](#sql)
## Как создать индекс?
Индекс можно создать либо с помощью выражения `CREATE INDEX`:
```sql
CREATE INDEX index_name ON table_name (column_name)
```
либо указав ограничение целостности в виде уникального `UNIQUE` или первичного `PRIMARY` ключа в операторе создания таблицы `CREATE TABLE`.
[к оглавлению](#sql)
## Что делает оператор `MERGE`?
`MERGE` позволяет осуществить слияние данных одной таблицы с данными другой таблицы. При слиянии таблиц проверяется условие, и если оно истинно, то выполняется `UPDATE`, а если нет - `INSERT`. При этом изменять поля таблицы в секции `UPDATE`, по которым идет связывание двух таблиц, нельзя.
[к оглавлению](#sql)
## В чем отличие между операторами `DELETE` и `TRUNCATE`?
`DELETE` - оператор DML, удаляет записи из таблицы, которые удовлетворяют критерию `WHERE` при этом задействуются триггеры, ограничения и т.д.
`TRUNCATE` - DDL оператор. удаляет таблицу (для мгновенной очистки всех строк) и создает ее заново. Причем если на эту таблицу есть ссылки `FOREGIN KEY` или таблица используется в репликации, то пересоздать такую таблицу не получится.
+ Оператор SQL TRUNCATE не ведет запись об удаленных данных в журнал событий.
+ SQL DELETE осуществляет блокировку построчно, оператор SQL TRUNCATE по всей странице целиком. Вследствие этого, оператор SQL TRUNCATE не возвращает никакого значения, SQL DELETE же, возвращает количество удаленных строк.
+ После применения оператора SQL DELETE возможно сделать откат операции и восстановить удаленные данные (команда ROLLBACK). При применении оператора SQL TRUNCATE этого сделать нельзя, однако в СУБД MS SQL Server, оператор может применяться в транзакциях.
[к оглавлению](#sql)
## Что делает оператор `EXPLAIN`?
```java
EXPLAIN имя_таблицы
EXPLAIN SELECT опции_выборки
```
Если оператор SELECT предваряется ключевым словом EXPLAIN, MySQL сообщит о том, как будет производиться обработка SELECT, и предоставит информацию о порядке и методе связывания таблиц.
При помощи EXPLAIN можно выяснить, когда стоит снабдить таблицы индексами, чтобы получить более быструю выборку, использующую индексы для поиска записей. Кроме того, можно проверить, насколько удачный порядок связывания таблиц был выбран оптимизатором. Заставить оптимизатор связывать таблицы в заданном порядке можно при помощи указания STRAIGHT_JOIN.
Для непростых соединений EXPLAIN возвращает строку информации о каждой из использованных в работе оператора SELECT таблиц. Таблицы перечисляются в том порядке, в котором они будут считываться. MySQL выполняет все связывания за один проход (метод называется "single-sweep multi-join"). Делается это так: MySQL читает строку из первой таблицы, находит совпадающую строку во второй таблице, затем - в третьей, и так далее. Когда обработка всех таблиц завершается, MySQL выдает выбранные столбцы и обходит в обратном порядке список таблиц до тех пор, пока не будет найдена таблица с наибольшим совпадением строк. Следующая строка считывается из этой таблицы и процесс продолжается в следующей таблице.
```java
********************** 1. row **********************
id: 1
select_type: SIMPLE
table: categories
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4
Extra:
1 row in set (0.00 sec)
```
+ id порядковый номер для каждого SELECTа внутри запроса (когда имеется несколько подзапросов)
select_type тип запроса SELECT.
+ SIMPLE — Простой запрос SELECT без подзапросов или UNIONов
+ PRIMARY данный SELECT самый внешний запрос в JOINе
+ DERIVED данный SELECT является частью подзапроса внутри FROM
+ SUBQUERY первый SELECT в подзапросе
+ DEPENDENT SUBQUERY подзапрос, который зависит от внешнего запроса
+ UNCACHABLE SUBQUERY не кешируемый подзапрос (существуют определенные условия для того, чтобы запрос кешировался)
+ UNION второй или последующий SELECT в UNIONе
+ DEPENDENT UNION второй или последующий SELECT в UNIONе, зависимый от внешнего запроса
+ UNION RESULT результат UNIONа
+ Table таблица, к которой относится выводимая строка
+ Type — указывает на то, как MySQL связывает используемые таблицы. Это одно из наиболее полезных полей в выводе потому, что может сообщать об отсутствующих индексах или почему написанный запрос должен быть пересмотрен и переписан.
Возможные значения:
+ System таблица имеет только одну строку
+ Const таблица имеет только одну соответствующую строку, которая проиндексирована. Это наиболее быстрый тип соединения потому, что таблица читается только один раз и значение строки может восприниматься при дальнейших соединениях как константа.
+ Eq_ref все части индекса используются для связывания. Используемые индексы: PRIMARY KEY или UNIQUE NOT NULL. Это еще один наилучший возможный тип связывания.
+ Ref все соответствующие строки индексного столбца считываются для каждой комбинации строк из предыдущей таблицы. Этот тип соединения для индексированных столбцов выглядит как использование операторов = или < = >
+ Fulltext соединение использует полнотекстовый индекс таблицы
+ Ref_or_null то же самое, что и ref, но также содержит строки со значением null для столбца
+ Index_merge соединение использует список индексов для получения результирующего набора. Столбец key вывода команды EXPLAIN будет содержать список использованных индексов.
+ Unique_subquery подзапрос IN возвращает только один результат из таблицы и использует первичный ключ.
+ Index_subquery тоже, что и предыдущий, но возвращает более одного результата.
+ Range индекс, использованный для нахождения соответствующей строки в определенном диапазоне, обычно, когда ключевой столбец сравнивается с константой, используя операторы вроде: BETWEEN, IN, >, >=, etc.
+ Index сканируется все дерево индексов для нахождения соответствующих строк.
+ All Для нахождения соответствующих строк используются сканирование всей таблицы. Это наихудший тип соединения и обычно указывает на отсутствие подходящих индексов в таблице.
+ Possible_keys показывает индексы, которые могут быть использованы для нахождения строк в таблице. На практике они могут использоваться, а могут и не использоваться. Фактически, этот столбец может сослужить добрую службу в деле оптимизации запросов, т.к значение NULL указывает на то, что не найдено ни одного подходящего индекса .
+ Key указывает на использованный индекс. Этот столбец может содержать индекс, не указанный в столбце possible_keys. В процессе соединения таблиц оптимизатор ищет наилучшие варианты и может найти ключи, которые не отображены в possible_keys, но являются более оптимальными для использования.
+ Key_len длина индекса, которую оптимизатор MySQL выбрал для использования. Например, значение key_len, равное 4, означает, что памяти требуется для хранения 4 знаков. На эту тему вот cсылка
+ Ref указываются столбцы или константы, которые сравниваются с индексом, указанным в поле key. MySQL выберет либо значение константы для сравнения, либо само поле, основываясь на плане выполнения запроса.
+ Rows отображает число записей, обработанных для получения выходных данных. Это еще одно очень важное поле, которое дает повод оптимизировать запросы, особенно те, которые используют JOINы и подзапросы.
+ Extra содержит дополнительную информацию, относящуюся к плану выполнения запроса. Такие значения как “Using temporary”, “Using filesort” и т.д могут быть индикатором проблемного запроса. С полным списком возможных значений вы можете ознакомиться здесь
[к оглавлению](#sql)
## Что такое _«RETURNING»_?
Иногда бывает полезно получать данные из модифицируемых строк в процессе их обработки. Это возможно с использованием предложения RETURNING, которое можно задать для команд INSERT, UPDATE и DELETE. Применение RETURNING позволяет обойтись без дополнительного запроса к базе для сбора данных и это особенно ценно, когда как-то иначе трудно получить изменённые строки надёжным образом.
Точно работает в PostgreSQL
```java
INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;
В команде UPDATE данные, выдаваемые в RETURNING, образуются новым содержимым изменённой строки. Например:
UPDATE products SET price = price * 1.10
WHERE price <= 99.99
RETURNING name, price AS new_price;
В команде DELETE данные, выдаваемые в RETURNING, образуются содержимым удалённой строки. Например:
DELETE FROM products
WHERE obsoletion_date = 'today'
RETURNING *;
```
[к оглавлению](#sql)
## Что такое хранимая процедура»_?
__Хранимая процедура__ — объект базы данных, представляющий собой набор SQL-инструкций, который хранится на сервере. Хранимые процедуры очень похожи на обыкновенные процедуры языков высокого уровня, у них могут быть входные и выходные параметры и локальные переменные, в них могут производиться числовые вычисления и операции над символьными данными, результаты которых могут присваиваться переменным и параметрам. В хранимых процедурах могут выполняться стандартные операции с базами данных (как DDL, так и DML). Кроме того, в хранимых процедурах возможны циклы и ветвления, то есть в них могут использоваться инструкции управления процессом исполнения.
Хранимые процедуры позволяют повысить производительность, расширяют возможности программирования и поддерживают функции безопасности данных. В большинстве СУБД при первом запуске хранимой процедуры она компилируется (выполняется синтаксический анализ и генерируется план доступа к данным) и в дальнейшем её обработка осуществляется быстрее.
[к оглавлению](#sql)
## Что такое _«триггер»_?
__Триггер (trigger)__ — это хранимая процедура особого типа, которую пользователь не вызывает непосредственно, а исполнение которой обусловлено действием по модификации данных: добавлением, удалением или изменением данных в заданной таблице реляционной базы данных. Триггеры применяются для обеспечения целостности данных и реализации сложной бизнес-логики. Триггер запускается сервером автоматически и все производимые им модификации данных рассматриваются как выполняемые в транзакции, в которой выполнено действие, вызвавшее срабатывание триггера. Соответственно, в случае обнаружения ошибки или нарушения целостности данных может произойти откат этой транзакции.
Момент запуска триггера определяется с помощью ключевых слов `BEFORE` (триггер запускается до выполнения связанного с ним события) или `AFTER` (после события). В случае, если триггер вызывается до события, он может внести изменения в модифицируемую событием запись. Кроме того, триггеры могут быть привязаны не к таблице, а к представлению (VIEW). В этом случае с их помощью реализуется механизм «обновляемого представления». В этом случае ключевые слова `BEFORE` и `AFTER` влияют лишь на последовательность вызова триггеров, так как собственно событие (удаление, вставка или обновление) не происходит.
[к оглавлению](#sql)
## Что такое _«курсор»_?
__Курсор__ — это объект базы данных, который позволяет приложениям работать с записями «по-одной», а не сразу с множеством, как это делается в обычных SQL командах.
Порядок работы с курсором такой:
+ Определить курсор (`DECLARE`)
+ Открыть курсор (`OPEN`)
+ Получить запись из курсора (`FETCH`)
+ Обработать запись...
+ Закрыть курсор (`CLOSE`)
+ Удалить ссылку курсора (`DEALLOCATE`). Когда удаляется последняя ссылка курсора, SQL освобождает структуры данных, составляющие курсор.
[к оглавлению](#sql)
## Опишите разницу типов данных `DATETIME` и `TIMESTAMP`.
`DATETIME` предназначен для хранения целого числа: `YYYYMMDDHHMMSS`. И это время не зависит от временной зоны настроенной на сервере.
Размер: 8 байт
`TIMESTAMP` хранит значение равное количеству секунд, прошедших с полуночи 1 января 1970 года по усреднённому времени Гринвича. При получении из базы отображается с учётом часового пояса. Размер: 4 байта
[к оглавлению](#sql)
## Для каких числовых типов недопустимо использовать операции сложения/вычитания?
В качестве операндов операций сложения и вычитания нельзя использовать числовой тип `BIT`.
[к оглавлению](#sql)
## Какое назначение у операторов `PIVOT` и `UNPIVOT` в Transact-SQL?
`PIVOT` и `UNPIVOT` являются нестандартными реляционными операторами, которые поддерживаются Transact-SQL.
Оператор `PIVOT` разворачивает возвращающее табличное значение выражение, преобразуя уникальные значения одного столбца выражения в несколько выходных столбцов, а также, в случае необходимости, объединяет оставшиеся повторяющиеся значения столбца и отображает их в выходных данных. Оператор `UNPIVOT` производит действия, обратные `PIVOT`, преобразуя столбцы возвращающего табличное значение выражения в значения столбца.
[к оглавлению](#sql)
## Расскажите об основных функциях ранжирования в Transact-SQL.
Ранжирующие функции - это функции, которые возвращают значение для каждой записи группы в результирующем наборе данных. На практике они могут быть использованы, например, для простой нумерации списка, составления рейтинга или постраничной навигации.
`ROW_NUMBER` функция нумерации в Transact-SQL, которая возвращает просто номер записи.
`RANK` возвращает ранг каждой записи. В данном случае, в отличие от `ROW_NUMBER`, идет уже анализ значений и в случае нахождения одинаковых возвращает одинаковый ранг с пропуском следующего.
`DENSE_RANK` так же возвращает ранг каждой записи, но в отличие от `RANK` в случае нахождения одинаковых значений возвращает ранг без пропуска следующего.
`NTILE` функция Transact-SQL, которая делит результирующий набор на группы по определенному столбцу.
[к оглавлению](#sql)
## Для чего используются операторы `INTERSECT`, `EXCEPT` в Transact-SQL?
Оператор `EXCEPT` возвращает уникальные записи из левого входного запроса, которые не выводятся правым входным запросом.
Оператор `INTERSECT` возвращает уникальные записи, выводимые левым и правым входными запросами.
[к оглавлению](#sql)
## Напишите запрос...
```sql
CREATE TABLE table (
id BIGINT(20) NOT NULL AUTO_INCREMENT,
created TIMESTAMP NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
```
Требуется написать запрос который вернет максимальное значение `id` и значение `created` для этого `id`:
```sql
SELECT id, created FROM table where id = (SELECT MAX(id) FROM table);
```
---
```sql
CREATE TABLE track_downloads (
download_id BIGINT(20) NOT NULL AUTO_INCREMENT,
track_id INT NOT NULL,
user_id BIGINT(20) NOT NULL,
download_time TIMESTAMP NOT NULL DEFAULT 0,
PRIMARY KEY (download_id)
);
```
Напишите SQL-запрос, возвращающий все пары `(download_count, user_count)`, удовлетворяющие следующему условию: `user_count` — общее ненулевое число пользователей, сделавших ровно `download_count` скачиваний `19 ноября 2010 года`:
```sql
SELECT DISTINCT download_count, COUNT(*) AS user_count
FROM (
SELECT COUNT(*) AS download_count
FROM track_downloads WHERE download_time="2010-11-19"
GROUP BY user_id)
AS download_count
GROUP BY download_count;
```
[к оглавлению](#sql)
# Источники
+ [Википедия](https://ru.wikipedia.org/wiki/SQL)
+ [Quizful](http://www.quizful.net/interview/sql)
[Вопросы для собеседования](README.md)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,122 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# Тестирование
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Тестирование](#тестирование)
- [Что такое _«модульное тестирование»_?](#что-такое-модульное-тестирование)
- [Что такое _«компонентное тестирование»_?](#что-такое-компонентное-тестирование)
- [Что такое _«интеграционное тестирование»_?](#что-такое-интеграционное-тестирование)
- [Чем интеграционное тестирование отличается от модульного?](#чем-интеграционное-тестирование-отличается-от-модульного)
- [Какие существуют виды тестовых объектов?](#какие-существуют-виды-тестовых-объектов)
- [Чем _stub_ отличается от _mock_?](#чем-stub-отличается-от-mock)
- [Что такое _«фикстуры»_?](#что-такое-фикстуры)
- [Какие аннотации фикстур существуют в JUnit?](#какие-аннотации-фикстур-существуют-в-junit)
- [Для чего в JUnit используется аннотация `@Ignore`?](#для-чего-в-junit-используется-аннотация-ignore)
- [Источники](#источники)
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/Test1.png)
## Что такое _«модульное тестирование»_?
__Модульное/компонентное тестирование (unit testing)__ - процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы. Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже оттестированных местах программы, а также облегчает обнаружение и устранение таких ошибок.
Модульные тесты можно условно поделить на две группы:
+ есты состояния (state based)_, проверяющие что вызываемый метод объекта отработал корректно, проверяя состояние тестируемого объекта после вызова метода.
+ есты взаимодействия (interaction tests)_, в которых тестируемый объект производит манипуляции с другими объектами. Применяются, когда требуется удостовериться, что тестируемый объект корректно взаимодействует с другими объектами.
[к оглавлению](#Тестирование)
## Что такое _«компонентное тестирование»_?
Проверяет функциональность и ищет дефекты в частях приложения, которые доступны и могут быть протестированы по-отдельности (модули программ, объекты, классы, функции и т.д.). Обычно проводится вызывая код, который необходимо проверить и при поддержке сред разработки, таких как фреймворки (frameworks - каркасы) для модульного тестирования или инструменты для отладки.
По-существу компонентные и модульные тестирования представляют одно и тоже, разница лишь в том, что в компонентном тестировании в качестве параметров функций используют реальные объекты и драйверы, а в модульном тестировании - конкретные значения.
[к оглавлению](#Тестирование)
## Что такое _«интеграционное тестирование»_?
__Интеграционное тестирование (integration testing)__ — это тестирование, проверяющие работоспособность двух или более модулей системы в совокупности — то есть нескольких объектов как единого блока. В тестах взаимодействия же тестируется конкретный, определенный объект и то, как именно он взаимодействует с внешними зависимостями.
[к оглавлению](#Тестирование)
## Чем интеграционное тестирование отличается от модульного?
С технологической точки зрения интеграционное тестирование является количественным развитием модульного, поскольку так же, как и модульное тестирование, оперирует интерфейсами модулей и подсистем и требует создания тестового окружения, включая заглушки на месте отсутствующих модулей. Основная разница между модульным и интеграционным тестированием состоит в целях, то есть в типах обнаруживаемых дефектов, которые, в свою очередь, определяют стратегию выбора входных данных и методов анализа.
> Допустим, есть класс, который при определенных условиях взаимодействует с web-сервисом через зависимый объект. И нам надо проверить, что определенный метод зависимого объекта действительно вызывается. Если в качестве зависимого класса передать:
> + реальный класс, работающий с web-сервисом, то это будет интеграционное тестирование.
> + заглушку, то это будет тестирование состояния.
> + шпиона, а в конце теста проверить, что определенный метод зависимого объекта действительно был вызван, то это будет тест взаимодействия.
[к оглавлению](#Тестирование)
## Какие существуют виды тестовых объектов?
__пустышка (dummy)__ - объект, который обычно передается в тестируемый класс в качестве параметра, но не имеет поведения: с ним ничего не происходит и никакие его методы не вызываются.
> Примером dummy-объектов являются new object(), null, «Ignored String» и т.д.
__фальшивка (fake object)__ применяется в основном для ускорения запуска ресурсоёмких тестов и является заменой тяжеловесного внешнего зависимого объекта его легковесной реализацией.
> Основные примеры — эмулятор базы данных (fake database) или фальшивый web-сервис.
__заглушка (test stub)__ используется для получения данных из внешней зависимости, подменяя её. При этом заглушка игнорирует все данные поступающие из тестируемого объекта, возвращая заранее определённый результат.
> Тестируемый объект использует чтение из конфигурационного файла? Тогда передаем ему заглушку `ConfigFileStub` возвращающую тестовые строки конфигурации без обращения к файловой системе.
__шпион (test spy)__ - разновидность заглушки, которая умеет протоколировать сделанные к ней обращения из тестируемой системы, чтобы проверить их правильность в конце теста. При этом фиксируется количество, состав и содержание параметров вызовов.
> Если существует необходимость проверки, что определённый метод тестируемого класса вызывался ровно 1 раз, то шпион - имменно то, что нам нужно.
__фикция (mock object)__ похож на _шпиона_, но обладает расширенной функциональностью, заранее заданными поведением и реакцией на вызовы.
[к оглавлению](#Тестирование)
## Чем _stub_ отличается от _mock_?
_stub_ используется как заглушка сервисов, методов, классов и т.д. с заранее запрограммированным ответом на вызовы.
_mock_ использует подмену результатов вызова, проверяет сам факт взаимодействия, протоколирует и контролирует его.
[к оглавлению](#Тестирование)
## Что такое _«фикстуры»_?
__Фикстуры (fixtures)__ - состояние среды тестирования, которое требуется для успешного выполнения теста. Основная задача фикстур заключается в подготовке тестового окружения с заранее фиксированным/известным состоянием, чтобы гарантировать повторяемость процесса тестирования.
[к оглавлению](#Тестирование)
## Какие аннотации фикстур существуют в JUnit?
+ `@BeforeClass` - определяет код, который должен единожды выполниться перед запуском набора тестовых методов.
+ `@AfterClass` - код, выполняемый один раз после исполнения набора тестовых методов.
+ `@Before` - определяет код, который должен выполняться каждый раз перд запуском любого тестовым методом.
+ `@After` - код, выполняемый каждый раз после исполнения любого тестового метода.
[к оглавлению](#Тестирование)
## Для чего в JUnit используется аннотация `@Ignore`?
`@Ignore` указывает JUnit на необходимость пропустить данный тестовый метод.
[к оглавлению](#Тестирование)
# Источники
+ [Википедия](https://ru.wikipedia.org/wiki/Тестирование_программного_обеспечения)
+ [Хабрахабр](https://habrahabr.ru/post/116372/)
+ [Интуит](http://www.intuit.ru/department/se/testing/5/2.html)
[Вопросы для собеседования](README.md)

@ -0,0 +1,133 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# UML
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [UML](#uml)
- [Что такое _UML_?](#что-такое-uml)
- [Что такое _«диаграмма»_, _«нотация»_ и _«метамодель»_ в UML?](#что-такое-диаграмма-нотация-и-метамодель-в-uml)
- [Какие существуют типы диаграмм?](#какие-существуют-типы-диаграмм)
- [Структурные диаграммы:](#структурные-диаграммы)
- [Диаграммы поведения:](#диаграммы-поведения)
- [Какие виды отношений существуют в структурной диаграмме классов?](#какие-виды-отношений-существуют-в-структурной-диаграмме-классов)
- [Взаимосвязи классов](#взаимосвязи-классов)
- [Взаимосвязи объектов классов](#взаимосвязи-объектов-классов)
- [#Общие взаимосвязи](#общие-взаимосвязи)
- [Источники](#источники)
## Что такое _UML_?
__UML__ это унифицированный графический язык моделирования для описания, визуализации, проектирования и документирования объектно-ориентированных систем. UML призван поддерживать процесс моделирования на основе объектно-ориентированного подхода, организовывать взаимосвязь концептуальных и программных понятий, отражать проблемы масштабирования сложных систем.
Отличительной особенностью UML является то, что словарь этого языка образуют графические элементы. Каждому графическому символу соответствует конкретная семантика, поэтому модель, созданная одним человеком, может однозначно быть понята другим человеком или программным средством, интерпретирующим UML. Отсюда, в частности, следует, что модель системы, представленная на UML, может автоматически быть переведена на объектно-ориентированный язык программирования, то есть, при наличии хорошего инструментального средства визуального моделирования, поддерживающего UML, построив модель, мы получим и заготовку программного кода, соответствующего этой модели.
[к оглавлению](#uml)
## Что такое _«диаграмма»_, _«нотация»_ и _«метамодель»_ в UML?
__Диаграмма__ - графическое представление совокупности элементов модели в форме связного графа, вершинам и ребрам (дугам) которого приписывается определенная семантика
__Нотация__ совокупность символов и правила их применения, используются для представления понятий и связей между ними.
Нотация диаграммы определяет способ представления, ассоциации, множественности. Причем эти понятия должны быть точно определены.
__Метамодель__ диаграмма, определяющая нотацию.
Метамодель помогает понять, что такое хорошо организованная, т.е. синтаксически правильная, модель.
[к оглавлению](#uml)
## Какие существуют типы диаграмм?
## Структурные диаграммы:
__классов (Class diagram)__ описывает структуру системы, демонстрирующая классы системы, их атрибуты, методы и зависимости между классами.
__объектов (Object diagram)__ демонстрирует полный или частичный снимок моделируемой системы в заданный момент времени. На диаграмме объектов отображаются экземпляры классов (объекты) системы с указанием текущих значений их атрибутов и связей между объектами.
__компонентов (Component diagram)__ показывает разбиение программной системы на структурные компоненты и связи (зависимости) между компонентами.
+ __развёртывания/размещения (Deployment diagram)__ служит для моделирования работающих узлов и артефактов, развёрнутых на них.
+ __пакетов (Package diagram)__ используется для организации элементов в группы по какому-либо признаку с целью упрощения структуры и организации работы с моделью системы.
+ __профилей (Profile diagram)__ действует на уровне метамодели и показывает стереотип класса или пакета.
+ __композитной/составной структуры (Composite structure diagram)__ демонстрирует внутреннюю структуру класса и, по возможности, взаимодействие элементов (частей) его внутренней структуры.
+ __кооперации (Collaboration diagram)__ показывает роли и взаимодействие классов в рамках кооперации.
## Диаграммы поведения:
__деятельности (Activity diagram)__ показывает разложение некоторой деятельности на её составные части. Под деятельностью понимается спецификация исполняемого поведения в виде координированного последовательного и параллельного выполнения подчинённых элементов — вложенных видов деятельности и отдельных действий, соединённых между собой потоками, которые идут от выходов одного узла к входам другого. Диаграммы деятельности используются при моделировании бизнес-процессов, технологических процессов, последовательных и параллельных вычислений.
__состояний/автомата/конечного автомата (State Machine diagram)__ представляет конечный автомат с простыми состояниями, переходами и композитными состояниями. Конечный автомат (State machine) — спецификация последовательности состояний, через которые проходит объект или взаимодействие в ответ на события своей жизни, а также ответные действия объекта на эти события. Конечный автомат прикреплён к исходному элементу (классу, кооперации или методу) и служит для определения поведения его экземпляров.
__вариантов использования/прецедентов (Use case diagram)__ отражает отношения существующие между актёрами и вариантами использования. Основная задача — представлять собой единое средство, дающее возможность заказчику, конечному пользователю и разработчику совместно обсуждать функциональность и поведение системы.
__взаимодействия (Interaction diagram)__:
+ __коммуникации (Communication diagram)__ изображает взаимодействия между частями композитной структуры или ролями кооперации при этом явно указываются отношения между элементами (объектами), а время как отдельное измерение не используется (применяются порядковые номера вызовов).
+ __последовательности (Sequence diagram)__ показывает взаимодействия объектов, упорядоченные по времени их проявления.
+ __обзора взаимодействия (Interaction overview diagram)__ — разновидность диаграммы деятельности, включающая фрагменты диаграммы последовательности и конструкции потока управления.
+ __синхронизации (Timing diagram)__ — альтернативное представление диаграммы последовательности, явным образом показывающее изменения состояния на линии жизни с заданной шкалой времени. Может быть полезна в приложениях реального времени.
[к оглавлению](#uml)
## Какие виды отношений существуют в структурной диаграмме классов?
## Взаимосвязи классов
__Обобщение (Generalization)__ показывает, что один из двух связанных классов (подтип) является частной формой другого (супертипа), который называется обобщением первого. На практике это означает, что любой экземпляр подтипа является также экземпляром супертипа. Обобщение также известно как аследование_, _«is a» взаимосвязь_ или _отношение «является»_.
> «Табурет» является подтипом «Мебели».
__Реализация (Implementation)__ — отношение между двумя элементами модели, в котором один элемент (клиент) реализует поведение, заданное другим (поставщиком). Реализация — отношение целое-часть. Поставщик, как правило является абстрактным классом или классом-интерфейсом.
> «Кровать» реализует поведение «Мебели для сна»
## Взаимосвязи объектов классов
__Зависимость (Dependency)__ обозначает такое отношение между классами, что изменение спецификации класса-поставщика может повлиять на работу зависимого класса, но не наоборот.
> «Расписание занятий» имеет зависимость от «Списка предметов». При изменении списка предметов расписание занятий будет вынуждено изменится. Однако изменение расписания занятий никак не влияет на список предметов.
__Ассоциация (Association)__ показывает, что объекты одной сущности (класса) связаны с объектами другой сущности таким образом, что можно перемещаться от объектов одного класса к другому. Является общим случаем композиции и агрегации.
> «Студент» и «Университет» имеют ассоциацию т.к. студент может учиться в университете и этой ассоциации можно присвоить имя «учится в».
__Агрегация (Aggregation)__ — это разновидность ассоциации в отношении между целым и его частями. Как тип ассоциации агрегация может быть именованной. Одно отношение агрегации не может включать более двух классов (контейнер и содержимое). Агрегация встречается, когда один класс является коллекцией или контейнером других. Причём по умолчанию, агрегацией называют агрегацию по ссылке, то есть когда время существования содержащихся классов не зависит от времени существования содержащего их класса. Если контейнер будет уничтожен, то его содержимое — нет.
> «Студент» не является неотъемлемой частью «Группы», но в то же время, группа состоит из студентов, поэтому следует использовать агрегацию.
__Композиция (Composition)__ — более строгий вариант агрегации. Известна также как агрегация по значению. Композиция имеет жёсткую зависимость времени существования экземпляров класса контейнера и экземпляров содержащихся классов. Если контейнер будет уничтожен, то всё его содержимое будет также уничтожено.
> «Факультет» является частью «Университета» и факультет без университета существовать не может, следовательно здесь подходит композиция.
## #Общие взаимосвязи
__Зависимость__ — это слабая форма отношения использования, при котором изменение в спецификации одного влечёт за собой изменение другого, причём обратное не обязательно. Возникает, когда объект выступает, например, в форме параметра или локальной переменной. Существует несколько именованных вариантов. Зависимость может быть между экземплярами, классами или экземпляром и классом.
__Уточнение отношений__ имеет отношение к уровню детализации. Один пакет уточняет другой, если в нём содержатся те же самые элементы, но в более подробном представлении.
__Мощность/кратность/мультипликатор отношения__ означает число связей между каждым экземпляром класса (объектом) в начале линии с экземпляром класса в её конце. Различают следующие типичные случаи:
| нотация | объяснение | пример |
|:----------:|:--------------------------:|:---------------------------------------------:|
| 0..1 | Ноль или один экземпляр | кошка имеет или не имеет хозяина |
| 1 | Обязательно один экземпляр | у кошки одна мать |
| 0..* или * | Ноль или более экземпляров | у кошки могут быть, а может и не быть котят |
| 1..* | Один или более экземпляров | у кошки есть хотя бы одно место, где она спит |
[к оглавлению](#uml)
# Источники
+ [Википедия](https://ru.wikipedia.org/wiki/UML)
+ [Информикус](http://www.informicus.ru/)
[Вопросы для собеседования](README.md)

@ -0,0 +1,377 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
1. Что такое WWW?
2. Что такое W3C?
3. Какие существуют уровни модели OSI?
4. Что такое TCP/IP?
5. Что такое UDP?
6. Чем отличаются TCP и UDP?
7. Что такое протокол передачи данных? Какие протоколы вы знаете?
8. Что такое HTTP и HTTPS? Чем они отличаются?
9. Что такое FTP?
10. Чем отличаются методы GET и POST?
11. Что такое MIME тип?
12. Что такое Web server?
13. Что такое Web application?
14. Что такое Application server?
15. Чем отличаются Web server и Application server?
16. Что такое AJAX? Как принципиально устроена эта технология?
17. Что такое WebSocket?
18. Что такое JSON?
19. Что такое JSON схема?
20. Что такое cookies?
21. Что такое «сессия»?
22. Что такое «авторизация» и «аутентификация»? Чем они отличаются?
23. Какие методы передачи данных вы знаете?
24. Чем отличаются методы get и post?
25. Что такое html?
26. Что такое xml?
27. Что такое css?
28. Что такое MIME type?
29. Что такое ORM, как это перевести и как это должно работать?
[Вопросы для собеседования](README.md)
# Основы Web
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Основы Web](#основы-web)
- [Что такое _WWW_?](#что-такое-www)
- [Что такое _W3C_?](#что-такое-w3c)
- [Какие существуют уровни модели _OSI_?](#какие-существуют-уровни-модели-osi)
- [Что такое _TCP/IP_?](#что-такое-tcpip)
- [Что такое _UDP_?](#что-такое-udp)
- [Чем отличаются _TCP_ и _UDP_?](#чем-отличаются-tcp-и-udp)
- [Что такое протокол передачи данных? Какие протоколы вы знаете?](#что-такое-протокол-передачи-данных-какие-протоколы-вы-знаете)
- [Что такое _HTTP_ и _HTTPS_? Чем они отличаются?](#что-такое-http-и-https-чем-они-отличаются)
- [Что такое _FTP_?](#что-такое-ftp)
- [Чем отличаются методы _GET_ и _POST_?](#чем-отличаются-методы-get-и-post)
- [Что такое _MIME тип_?](#что-такое-mime-тип)
- [Что такое _Web server_?](#что-такое-web-server)
- [Что такое _Web application_?](#что-такое-web-application)
- [Что такое _Application server_?](#что-такое-application-server)
- [Чем отличаются _Web server_ и _Application server_?](#чем-отличаются-web-server-и-application-server)
- [Что такое _AJAX_? Как принципиально устроена эта технология?](#что-такое-ajax-как-принципиально-устроена-эта-технология)
- [Что такое _WebSocket_?](#что-такое-websocket)
- [Что такое _JSON_?](#что-такое-json)
- [Что такое _JSON схема_?](#что-такое-json-схема)
- [Что такое _cookies_?](#что-такое-cookies)
- [Что такое _«сессия»_?](#что-такое-сессия)
- [Что такое _«авторизация»_ и _«аутентификация»_? Чем они отличаются?](#что-такое-авторизация-и-аутентификация-чем-они-отличаются)
- [Источники](#источники)
## Что такое _WWW_?
__WWW, World Wide Web (Всемирная паутина)__ — распределённая система, предоставляющая доступ к связанным между собой документам, расположенным на различных компьютерах, подключённых к Интернету. Для обозначения этого термина также используют слово _web_.
[к оглавлению](#Основы-web)
## Что такое _W3C_?
__W3C, World Wide Web Consortium (Консорциум Всемирной паутины)__ — организация, разрабатывающая и внедряющая технологические стандарты для WWW.
W3C разрабатывает для Интернета единые принципы и стандарты, называемые рекомендациями» (W3C Recommendations)_, которые затем внедряются производителями программ и оборудования. Таким образом достигается совместимость между программными продуктами и аппаратурой различных компаний.
[к оглавлению](#Основы-web)
## Какие существуют уровни модели _OSI_?
| # | Уровень (layer) | Тип данных (PDU) | Функции | Примеры |
|--:|--------------------------------------------------|:-----------------------------------------:|----------------------------------------------------------|:--------------------------:|
| 7 | Прикладной (application) | - | Доступ к сетевым службам | HTTP, FTP |
| 6 | Представительский (представления) (presentation) | - | Представление и шифрование данных | ASCII, JPEG |
| 5 | Сеансовый (session) | - | Управление сеансом связи | RPC, PAP |
| 4 | Транспортный (transport) | Сегменты(segment) / Дейтаграммы(datagram) | Прямая связь между конечными пунктами и надежность | TCP, UDP |
| 3 | Сетевой (network) | Пакеты (packet) | Определение маршрута и логическая адресация | IP, AppleTalk |
| 2 | Канальный (data link) | Биты (bit) / Кадры (frame) | Физическая адресация | Ethernet, IEEE 802.2, L2TP |
| 1 | Физический (physical) | Биты (bit) | Работа со средой передачи, сигналами и двоичными данными | USB, витая пара |
[к оглавлению](#Основы-web)
## Что такое _TCP/IP_?
__TCP/IP__ - это два основных сетевых протокола Internet. Часто это название используют и для обозначения сетей, работающих на их основе.
__IP (Internet Protocol)__ - маршрутизируемый протокол, отвечающий за IP-адресацию, маршрутизацию, фрагментацию и восстановление пакетов. В его задачу входит продвижение пакета между сетями от одного маршрутизатора до другого и тех пор, пока пакет не попадет в сеть назначения. В отличие от протоколов прикладного и транспортного уровней, протокол IP разворачивается не только на хостах, но и на всех шлюзах (маршрутизаторах). Этот протокол работает без установления соединения и без гарантированной доставки.
В настоящее время используются следующие две версии протокола IP:
+ _IPv6_ — IP-адрес имеет разрядность 128 бит и записывается в виде восьми 16-битных полей, с использованием шестнадцатеричной системы счисления и с возможностью сокращения двух и более последовательных нулевых полей до `::`, например: `2001:db8:42::1337:cafe`
+ _IPv4_ — IP-адрес имеет разрядность 32 бита и записывается в виде четырех десятичных чисел в диапазоне 0255 через точку, например: `192.0.2.34`.
__TCP (Transfer Control Protocol)__ - протокол, обеспечивающий надежную, требующую логического соединения связь между двумя компьютерами. Отвечает за установление соединения, упорядочивание посылаемых пакетов и восстановление пакетов, потерянных в процессе передачи.
Стек протоколов _TCP/IP_ включает в себя четыре уровня:
1. анальный уровень (link layer)_ - например Ethernet, IEEE 802.11 Wireless Ethernet, физическая среда и принципы кодирования информации
2. _сетевой уровень (Internet layer)_ - например IP
3. ранспортный уровень (transport layer)_ - например TCP, UDP
4. _прикладной уровень (application layer)_ - например HTTP, FTP, DNS
TCP-соединение двух узлов начинается с _handshake (рукопожатия)_:
+ Узел _A_ посылает узлу _B_ специальный пакет `SYN` — приглашение к соединению
+ _B_ отвечает пакетом `SYN-ACK` — согласием об установлении соединения
+ _A_ посылает пакет `ACK` — подтверждение, что согласие получено
После этого _TCP соединение_ считается установленным и приложения, работающие в этих узлах, могут посылать друг другу пакеты с данными.
В заголовке _TCP/IP_ пакета указывается:
+ IP-адрес отправителя
+ IP-адрес получателя
+ Номер порта
[к оглавлению](#Основы-web)
## Что такое _UDP_?
__UDP, User Datagram Protocol (Протокол пользовательских датаграмм)__ — протокол, который обеспечивает доставку без требований соединения с удаленным модулем UDP и обязательного подтверждения получения.
К заголовку IP-пакета UDP добавляет всего четыре поля по 2 байта каждое:
1. _поле порта источника (source port)_
2. _поле порта пункта назначения (destination port)_
3. _поле длины (length)_
4. _поле контрольной суммы (checksum)_
Поля «порт источника» и «контрольная сумма» не являются обязательными для использования в IPv4. В IPv6 необязательно только поле «порт отправителя».
UDP используется _DNS_, _SNMP_, _DHCP_ и другими приложениями.
[к оглавлению](#Основы-web)
## Чем отличаются _TCP_ и _UDP_?
__TCP__ — ориентированный на соединение протокол, что означает необходимость «рукопожатия» для установки соединения между двумя хостами. Как только соединение установлено, пользователи могут отправлять данные в обоих направлениях.
+ _Надёжность_ — TCP управляет подтверждением, повторной передачей и тайм-аутом сообщений. Производятся многочисленные попытки доставить сообщение. Если оно потеряется на пути, сервер вновь запросит потерянную часть. В TCP нет ни пропавших данных, ни (в случае многочисленных тайм-аутов) разорванных соединений.
+ _Упорядоченность_ — если два сообщения последовательно отправлены, первое сообщение достигнет приложения-получателя первым. Если участки данных приходят в неверном порядке, TCP отправляет неупорядоченные данные в буфер до тех пор, пока все данные не могут быть упорядочены и переданы приложению.
+ _Тяжеловесность_ — TCP необходимо три пакета для установки соединения перед тем, как отправить данные. TCP следит за надёжностью и перегрузками.
+ отоковость_ — данные читаются как поток байтов, не передается никаких особых обозначений для границ сообщения или сегментов.
__UDP__ — более простой, основанный на сообщениях протокол без установления соединения. Протоколы такого типа не устанавливают выделенного соединения между двумя хостами. Связь достигается путём передачи информации в одном направлении от источника к получателю без проверки готовности или состояния получателя.
+ _Ненадёжность_ — когда сообщение посылается, неизвестно, достигнет ли оно своего назначения — оно может потеряться по пути. Нет таких понятий как подтверждение, повторная передача, тайм-аут.
+ _Неупорядоченность_ — если два сообщения отправлены одному получателю, то порядок их достижения цели не может быть предугадан.
+ егковесность_ — никакого упорядочивания сообщений, никакого отслеживания соединений и т. д. Это лишь транспортный уровень.
+ атаграммы_ — пакеты посылаются по отдельности и проверяются на целостность только если они прибыли. Пакеты имеют определенные границы, которые соблюдаются после получения, то есть операция чтения на получателе выдаст сообщение таким, каким оно было изначально послано.
+ _Отсутствие контроля перегрузок_ — для приложений с большой пропускной способностью существует шанс вызвать коллапс перегрузок, если только они не реализуют меры контроля на прикладном уровне.
[к оглавлению](#Основы-web)
## Что такое протокол передачи данных? Какие протоколы вы знаете?
__Протокол передачи данных__ — набор соглашений интерфейса логического уровня, которые определяют обмен данными между различными программами. Эти соглашения задают единообразный способ передачи сообщений и обработки ошибок при взаимодействии программного обеспечения разнесённой в пространстве аппаратуры, соединённой тем или иным интерфейсом.
Наиболее известные протоколы передачи данных:
+ HTTP (Hyper Text Transfer Protocol)
+ FTP (File Transfer Protocol)
+ POP3 (Post Office Protocol)
+ SMTP (Simple Mail Transfer Protocol)
+ TELNET (TErminaL NETwork)
[к оглавлению](#Основы-web)
## Что такое _HTTP_ и _HTTPS_? Чем они отличаются?
__HTTP, HyperText Transfer Protocol (Протокол передачи гипертекста)__ — протокол прикладного уровня передачи данных.
Основой HTTP является технология «клиент-сервер»:
+ отребители (клиенты)_, которые инициируют соединение и посылают запрос;
+ оставщики (серверы)_, которые ожидают соединения для получения запроса, производят необходимые действия и возвращают обратно сообщение с результатом.
Для идентификации ресурсов HTTP использует глобальные URI.
HTTP не сохраняет своего состояния. Это означает отсутствие сохранения промежуточного состояния между парами «запрос-ответ».
Структура протокола:
1. _Стартовая строка (starting line)_ — определяет тип сообщения;
2. _Заголовки (headers)_ — характеризуют тело сообщения, параметры передачи и прочие сведения;
3. _Тело сообщения (message body)_ — непосредственно данные сообщения. Обязательно должно отделяться от заголовков пустой строкой.
Заголовки и тело сообщения могут отсутствовать, но стартовая строка является обязательным элементом, так как указывает на тип запроса/ответа.
__HTTPS, HyperText Transfer Protocol Secure__ — расширение протокола HTTP, поддерживающее шифрование. Данные, передаваемые по протоколу HTTPS, «упаковываются» в криптографический протокол SSL или TLS, что обеспечивает защиту от атак, основанных на прослушивании сетевого соединения (при условии, что будут использоваться шифрующие средства и сертификат сервера проверен и ему доверяют).
__Различия _HTTP_ и _HTTPS___:
+ HTTPS является расширением HTTP.
+ HTTP использует не зашифрованное соединение. Соединение по HTTPS поддерживает шифрование.
+ Работа по HTTP быстрей и менее ресурсоёмко, т.к. шифрование HTTPS требует дополнительных затрат.
+ Порты по умолчанию: в случае HTTP это TCP-порт `80`, для HTTPS - TCP-порт `443`.
[к оглавлению](#Основы-web)
## Что такое _FTP_?
__FTP, File Transfer Protocol (Протокол передачи файлов)__ — протокол передачи файлов между компьютерами в сети TCP. С его помощью можно подключаться к FTP-серверам, просматривать содержимое их каталогов и загружать файлы с сервера или на сервер. Протокол построен на архитектуре «клиент-сервер» и использует разные сетевые соединения для передачи команд и данных между клиентом и сервером.
По умолчанию использует TCP-порт `21`.
[к оглавлению](#Основы-web)
## Чем отличаются методы _GET_ и _POST_?
__GET__ передает данные серверу используя URL, тогда как __POST__ передает данные, используя тело HTTP запроса. Длина URL ограничена 1024 символами, это и будет верхним ограничением для данных, которые можно отослать через GET. POST может отправлять гораздо большие объемы данных. Лимит устанавливается web-server и составляет обычно около 2 Mb.
Передача данных методом POST более безопасна, чем методом GET, так как секретные данные (например пароль) не отображаются напрямую в web-клиенте пользователя, в отличии от URL, который виден почти всегда. Иногда это преимущество превращается в недостатком - вы не сможете послать данные за кого-то другого.
[к оглавлению](#Основы-web)
## Что такое _MIME тип_?
__MIME, Multipurpose Internet Mail Extension (Многоцелевые расширения Интернет-почты)__ — спецификация для передачи по сети файлов различного типа: изображений, музыки, текстов, видео, архивов и др. В HTML указание MIME-типа используется при передаче данных форм и вставки на страницу различных объектов.
[к оглавлению](#Основы-web)
## Что такое _Web server_?
__Web server (Веб-сервер)__ — сервер, принимающий HTTP-запросы от клиентов и выдающий им HTTP-ответы. Так называют как программное обеспечение, выполняющее функции web-сервера, так и непосредственно компьютер, на котором это программное обеспечение работает.
Web-серверы могут иметь различные дополнительные функции, например:
+ автоматизация работы web-страниц;
+ ведение журнала обращений пользователей к ресурсам;
+ аутентификация и авторизация пользователей;
+ поддержка динамически генерируемых страниц;
+ поддержка HTTPS для защищённых соединений с клиентами.
Наиболее известные web-серверы:
+ Apache
+ Microsoft IIS
+ nginx
[к оглавлению](#Основы-web)
## Что такое _Web application_?
__Web application (Веб-приложение)__ - клиент-серверное приложение, в котором клиентом выступает браузер, а сервером — web-сервер. Логика web application распределена между сервером и клиентом, хранение данных осуществляется, преимущественно, на сервере, а обмен информацией происходит по сети. Одним из преимуществ такого подхода является тот факт, что клиенты не зависят от конкретной операционной системы пользователя, поэтому web application является кроссплатформенным сервисом.
[к оглавлению](#Основы-web)
## Что такое _Application server_?
__Application Server (Сервер приложений)__ — программа, представляющая собой сервер, который занимается системной поддержкой приложений и обеспечивает их жизненный цикл в соответствии с правилами, определёнными в спецификациях. Может работать как полноценный самостоятельный web-сервер или быть поставщиком страниц для другого web-сервера. Обеспечивает обмен данными между приложениями и клиентами, берёт на себя выполнение таких функций, как создание программной среды для функционирующего приложения, идентификацию и авторизацию клиентов, организацию сессии для каждого из них.
Наиболее известные серверы приложений Java:
+ Apache Tomcat
+ Jetty
+ JBoss
+ GlassFish
+ IBM WebSphere
+ Oracle Weblogic
[к оглавлению](#Основы-web)
## Чем отличаются _Web server_ и _Application server_?
Понятие web server относится скорее к способу передачи данных (конкретно, по протоколу HTTP), в то время как понятие Application server относится к способу выполнения этих самых приложений (конкретно, удаленная обработка запросов клиентов при помощи каких-то программ, размещенных на сервере). Эти понятия нельзя ставить в один ряд. Они обозначают разные признаки программы. Какие-то программы удовлетворяют только одному признаку, какие-то - нескольким сразу.
Apache Tomcat умеет выполнять приложения? Да, значит он является application server. Apache Tomcat умеет отдавать данные по HTTP? - Да. Следовательно он является web server.
Возьмите какую-нибудь базу данных, в которой на хранимых процедурах описана сложная логика и можно в ответ на SQL-запросы отправлять даже sms. Такую базу данных можно назвать application server, но web server - уже нет, потому что все это не работает с клиентом по HTTP протоколу.
Возьмите чистый Apache, в котором не включены никакие модули для поддержки языков программирования. Он умеет отдавать только статичные файлы и картинки по протоколу HTTP. Это web server, но не application server. Включите модуль для поддержки PHP и разместите там программу на PHP, которая делает запросы к базе данных и динамически формирует страницы. Теперь Apache стал и application server.
[к оглавлению](#Основы-web)
## Что такое _AJAX_? Как принципиально устроена эта технология?
__AJAX, Asynchronous Javascript and XML (Асинхронный Javascript и XML)__ — подход к построению интерактивных пользовательских интерфейсов web-приложений, заключающийся в «фоновом» обмене данными браузера и web-сервера. В результате, при обновлении данных web-страница не перезагружается полностью и web-приложения становятся быстрее и удобнее.
При использовании AJAX:
1. Пользователь заходит на web-страницу и взаимодействует с каким-нибудь её элементом.
2. Скрипт на языке JavaScript определяет, какая информация необходима для обновления страницы.
3. Браузер отправляет соответствующий запрос на web-сервер.
4. Web-сервер возвращает только ту часть документа, на которую пришёл запрос.
5. Скрипт вносит изменения с учётом полученной информации (без полной перезагрузки страницы).
AJAX базируется на двух основных принципах:
1. использование технологии динамического обращения к серверу «на лету» (без перезагрузки страницы полностью) через динамическое создание:
+ очерних фреймов_;
+ ега `<script>`_;
+ ега `<img>`_.
2. использование _DHTML_ для динамического изменения содержания страницы;
AJAX не является самостоятельной технологией, это концепция использования нескольких смежных технологий:
+ _(X)HTML_, _CSS_ для подачи и стилизации информации;
+ _DOM-модель_, операции над которой производятся Javascript на стороне клиента, для обеспечения динамического отображения и взаимодействия с информацией;
+ _XMLHttpRequest_ или другой транспорт (_IFrame_, _SCRIPT-тег_, _..._) для асинхронного обмена данными с web-сервером;
+ _JSON_ или любой другой подходящий формат (_форматированный HTML_, екст_, _XML_, _..._) для обмена данными.
[к оглавлению](#Основы-web)
## Что такое _WebSocket_?
__WebSocket__ — протокол полнодуплексной связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и web-сервером в режиме реального времени.
Протокол _WebSocket_ определяет две URI схемы
+ `ws:` - нешифрованное соединение
+ `wss:` - шифрованное соединение
[к оглавлению](#Основы-web)
## Что такое _JSON_?
__JSON, JavaScript Object Notation__ — текстовый формат обмена данными, основанный на JavaScript.
JSON представляет собой (в закодированном виде) одну из двух структур:
+ _Набор пар «ключ:значение»_;
+ _Упорядоченный набор значений_.
Ключом может быть только строка (регистрозависимая: имена с буквами в разных регистрах считаются разными).
В качестве значений могут быть использованы:
+ _Объект_ — неупорядоченное множество пар «ключ:значение», заключённое в фигурные скобки `{ }`. Ключ описывается строкой, между ним и значением стоит символ `:`. Пары ключ-значение отделяются друг от друга запятыми;
+ _Массив (одномерный)_ — упорядоченное множество значений. Массив заключается в квадратные скобки `[ ]`. Значения разделяются запятыми.
+ _Число_;
+ _Литералы_ `true`, `false` и `null`;
+ _Строка_ — упорядоченное множество из нуля или более символов Unicode, заключенное в кавычки `" "`. Символы могут быть указаны с использованием escape-последовательностей, начинающихся с обратной косой черты `\`, или записаны шестнадцатеричным кодом в кодировке UTF-8 в виде `\uFFFF`.
[к оглавлению](#Основы-web)
## Что такое _JSON схема_?
__JSON Schema__ — один из языков описания структуры JSON-документа, используя синтаксис JSON.
Это самоописательный язык: при его использовании для обработки данных и описания их допустимости могут использоваться одни и те же инструменты сериализации/десериализации.
[к оглавлению](#Основы-web)
## Что такое _cookies_?
__Сookies («куки»)__ — небольшой фрагмент данных, отправленный web-сервером и хранимый на устройстве пользователя. Всякий раз при попытке открыть страницу сайта, web-клиент пересылает соответствующие этому сайту cookies web-серверу в составе HTTP-запроса. Применяется для сохранения данных на стороне пользователя и на практике обычно используется для:
+ аутентификации пользователя;
+ хранения персональных предпочтений и настроек пользователя;
+ отслеживания состояния сеанса доступа пользователя;
+ ведения разнообразной статистики.
[к оглавлению](#Основы-web)
## Что такое сессия»_?
__Сессия__ промежуток времени между первым и последним запросами, которые пользователь отправляет со своего устройства на сервер сайта. Завершается сессия в случае, если со стороны пользователя не поступало запросов в течение определенного промежутка времени или же при обрыве связи.
[к оглавлению](#Основы-web)
## Что такое авторизация»_ и аутентификация»_? Чем они отличаются?
__Аутентификация__ - это проверка соответствия субъекта и того, за кого он пытается себя выдать, с помощью некой уникальной информации (отпечатки пальцев, цвет радужки, голос и тд.), в простейшем случае - с помощью имени входа и пароля.
__Авторизация__ - это проверка и определение полномочий на выполнение некоторых действий (например, чтение файла) в соответствии с ранее выполненной аутентификацией.
Очевидно, что это разные понятия, но при этом без первого не может быть второго и наоборот. То есть имея разрешение на работу, вы не сможете оказаться на рабочем месте без предъявления пропуска, равно как и нет смысла в демонстрации пропуска, если вы не планируете работать. Именно тот факт, что одного не бывает без другого, и вызывает у людей заблуждение, что это одно и то же.
[к оглавлению](#Основы-web)
# Источники
+ [Википедия](https://ru.wikipedia.org/)
[Вопросы для собеседования](README.md)

@ -0,0 +1,208 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# XML
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [XML](#xml)
- [Что такое _XML_?](#что-такое-xml)
- [Что такое _DTD_?](#что-такое-dtd)
- [Чем _well-formed XML_ отличается от _valid XML_?](#чем-well-formed-xml-отличается-от-valid-xml)
- [Что такое «_пространство имен_» в XML?](#что-такое-пространство-имен-в-xml)
- [Что такое XSD? В чём его преимущества перед XML DTD?](#что-такое-xsd-в-чём-его-преимущества-перед-xml-dtd)
- [Какие типы существуют в XSD?](#какие-типы-существуют-в-xsd)
- [Какие вы знаете методы чтения XML? Опишите сильные и слабые стороны каждого метода.](#какие-вы-знаете-методы-чтения-xml-опишите-сильные-и-слабые-стороны-каждого-метода)
- [Когда следует использовать _DOM_, а когда _SAX_, _StAX_ анализаторы?](#когда-следует-использовать-dom-а-когда-sax-stax-анализаторы)
- [Какие вы знаете способы записи XML?](#какие-вы-знаете-способы-записи-xml)
- [Что такое _JAXP_?](#что-такое-jaxp)
- [Что такое _XSLT_?](#что-такое-xslt)
- [Источники](#источники)
## Что такое _XML_?
__XML, eXtensible Markup Language (расширяемый язык разметки)__ - язык с простым формальным синтаксисом, хорошо приспособленный для создания и обработки документов программами и одновременно удобный для чтения и создания документов человеком.
XML расширяем, он не фиксирует разметку, используемую в документах и разработчик волен создавать разметку в соответствии с потребностями конкретной области, будучи ограниченным лишь синтаксическими правилами языка.
[к оглавлению](#xml)
## Что такое _DTD_?
__DTD, Document Type Definition (определение типа документа)__ — это заранее определённый свод правил, задающий связи между элементами и атрибутами.
> Например, DTD для HTML гласит, что тэг `DIV` должен быть внутри тэга `BODY` и может встречаться многократно, `TITLE` — в `HEAD` и всего один раз, а `SCRIPT` и там, и там сколь угодно раз.
DTD обычно описывается непосредственно в документе в виде строки-формулировки, начинающейся с `<!DOCTYPE ... >` или отдельном файле.
[к оглавлению](#xml)
## Чем _well-formed XML_ отличается от _valid XML_?
В зависимости от уровня соответствия стандартам документ может быть «well-formed» («правильно построенный»), либо «valid» («действительный»).
Основные признаки _well-formed XML_ следуют из формального описания стандарта:
+ Документ имеет ровно один корневой элемент, в котором лежат все остальные. То есть, `<document>...</document><appendix>...</appendix>` - это не XML-документ.
+ Все открытые теги обязаны быть закрыты. HTML, например, допускает не закрывать многие теги (`<p>`, `<body>`, `<li>`, `<td>` и многие другие). В XML так делать нельзя.
+ Для одиночных тегов (типа `<br>`) , чтобы отличать их от открывающих, предусмотрена специальная запись: `<br/>`. Но можно написать и полностью `<br></br>`.
+ Имена тегов регистрозависимые. Если вы открываете тег `<SiteDescription>`, то его надо закрывать именно таким же, `</sitedescription>` не допускается.
+ Теги не могут нарушать вложенность. Вот такого не должно быть: `<em><b>...</em></b>`.
+ Все атрибуты тегов обязаны быть заключены в двойные кавычки (`"`).
+ Есть три символа - `<`, `>` и `&`, которые обязаны быть экранированы везде с помощью `&lt;`, `&gt;` и `&amp;`. Внутри атрибутов надо экранировать еще и двойную кавычку с помощью `&quot;`.
+ Все символы в документе обязаны соответствовать заявленной кодировке.
Документ является _valid_, если он сформирован с соблюдением всех синтаксических правил корректности конкретного XML, т.е. соответствует _DTD_.
__*well-formed XML* - корректен синтаксически (может быть разобран парсером), а _valid XML_ - корректен как синтаксически так и семантически (удовлетворяет правилам заранее описанных словаря и грамматики (DTD)).__
[к оглавлению](#xml)
## Что такое «_пространство имен_» в XML?
__Пространство имён XML (XML namespace)__ - это идентифицируемая с помощью ссылки URI коллекция имен, используемых в XML документах для обозначения типов элементов и именования атрибутов. Пространство имен XML отличается от тех «пространств имен», которые обычно используются в компьютерных дисциплинах, тем, что в варианте для XML оно имеет внутреннюю структуру, и, с математической точки зрения, набором не является.
> Пространства имён объявляются с помощью XML атрибута `xmlns`, значением которого должен быть _URI_ и префикса, однозначно идентифицирующего пространство имён каждого элемента.
Все имена элементов в пределах пространства имён должны быть уникальны.
В общем случае пространство имён XML не требует, чтобы был определён его словарь.
XML-документ может содержать имена элементов и атрибутов из нескольких словарей XML. В каждом словаре задано своё пространство имён — так разрешается проблема неоднозначности имён элементов и атрибутов.
[к оглавлению](#xml)
## Что такое XSD? В чём его преимущества перед XML DTD?
__XSD, XML Schema Definition, XML Schema (XML схема)__ — язык описания структуры XML-документа. В частности, XML Schema описывает:
+ _словарь_ - имена элементов и атрибутов;
+ одель содержания_ - взаимосвязи между элементами и атрибутами, а также их
+ _структуру_ документа;
+ используемые _типы данных_.
__Преимущества XSD перед DTD__ заключаются в следующем:
+ DTD, в отличии от XSD, не является XML и имеет свой собственный синтаксис. В связи с этим могут возникать разнообразные проблемы с кодировкой и верификацией XML-документов.
+ При использовании XSD XML-парсер может проверить не только правильность синтаксиса XML документа, но также его структуру, модель содержания и типы данных. В XML DTD существует лишь один тип данных строка и если, например, в числовом поле будет текст, то документ всё же сможет пройти верификацию, так как XML DTD не сможет проверить тип данных.
+ Нельзя поставить в соответствие одному XML документу больше одного DTD. А следовательно и верифицировать документ можно лишь одним DTD описанием. XSD расширяем, и позволяет подключать несколько словарей для описания типовых задач.
+ XSD обладает встроенными средствами документирования, позволяющими создавать самодостаточные документы, не требующие дополнительного описания.
[к оглавлению](#xml)
## Какие типы существуют в XSD?
__Простой тип__ - это определение типа для значения, которое может использоваться в качестве содержимого элемента или атрибута. Этот тип данных не может содержать элементы или иметь атрибуты.
```xsd
<xsd:element name='price' type='xsd:decimal'/>
...
<price>45.50</price>
```
__Сложный тип__ - это определение типа для элементов, которые могут содержать атрибуты и другие элементы.
```xsd
<xsd:element name='price'>
<xsd:complexType base='xsd:decimal'>
<xsd:attribute name='currency' type='xsd:string'/>
</xsd:complexType>
</xsd:element>
...
<price currency='US'>45.50</price>
```
[к оглавлению](#xml)
## Какие вы знаете методы чтения XML? Опишите сильные и слабые стороны каждого метода.
__DOM (Document Object Model)__ - _объектный_ - считывает XML, воссоздавая его в памяти в виде объектной структуры при этом XML документ представляется в виде набора тегов узлов. Каждый узел может иметь неограниченное количество дочерних узлов. Каждый дочерний тоже может содержать несколько уровней потомков или не содержать их вовсе. Таким образом в итоге получается некое дерево.
> Низкая скорость работы.
> Расходует много памяти.
> Прост в программировании.
> Если в XML много объектов с перекрёстными ссылками друг на друга, достаточно дважды пройтись по документу: первый раз создать объекты без ссылок и заполнить словарь «название-объект», второй раз — восстановить ссылки.
> При ошибке в XML в памяти остаётся полусозданная структура XML, которая будет автоматически уничтожена.
> Пригоден как для чтения так и для записи.
__SAX (Simple API for XML)__ _событийный_ - читает XML документ, реагируя на появляющиеся события (открывающий или закрывающий тег, строку, атрибут) вызовом предоставляемых приложением обработчиков событий. При этом, в отличии от DOM, не сохраняет документ в памяти.
> Высокая скорость работы
> Расходует мало памяти.
> ➗ Довольно сложен в программировании.
> Если в XML много объектов с перекрёстными ссылками друг на друга, надо организовать временное хранение строковых ссылок, чтобы потом, когда документ будет считан, преобразовать в указатели.
> При ошибке в XML в памяти остаётся полусозданная структура предметной отрасли; программист должен своими руками корректно уничтожить её.
> Пригоден только для чтения.
__StAX (Stream API for XML)__ _потоковый_ - состоящий из двух наборов API для обработки XML, которые обеспечивают разные уровни абстракции. API с использованием курсора позволяет приложениям работать с XML как с потоком лексем (или событий); приложение может проверить статус анализатора и получить информацию о последней проанализированной лексеме, а затем перейти к следующей. Второй, высокоуровневый API, использующий итераторы событий, позволяет приложению обрабатывать XML как серию объектов событий, каждый из которых взаимодействует с фрагментом XML-структуры приложения. Всё, что требуется от приложения - это определить тип синтаксически разобранного события, отнести его к соответствующему конкретному типу и использовать соответствующие методы для получения информации, относящейся к событию.
> ➗ Сохраняет преимущества, которые есть в SAX по сравнению с DOM.
> Не основан на обратных вызовах обработчиков, приложению не придется обслуживать эмулированное состояние анализатора, как это происходит при использовании SAX.
> Пригоден только для чтения.
[к оглавлению](#xml)
## Когда следует использовать _DOM_, а когда _SAX_, _StAX_ анализаторы?
DOM - естественный выбор, когда объектом предметной области является сам XML: когда нужно знать и иметь возможность изменять структуру документа, а также в случае многократного использования информации из документа.
Для быстрого одноразового чтения оптимальным является использование SAX или StAX.
[к оглавлению](#xml)
## Какие вы знаете способы записи XML?
__Прямая запись__ - пишет XML тег за тегом, атрибут за атрибутом.
> Высокая скорость работы.
> Экономия памяти: при использовании не создаётся промежуточных объектов.
> Пригоден только для записи.
__Запись DOM (Document Object Model)__ - создаёт полную структуру XML и только потом записывает её.
> Низкая скорость работы.
> Не оптимальный расход памяти.
> Пригоден как для записи так и для чтения.
[к оглавлению](#xml)
## Что такое _JAXP_?
__JAXP, The Java API for XML Processing (Java API для обработки XML)__ — набор API, упрощающих обработку XML данных в программах написанных на Java. Содержит реализации DOM, SAX и StAX парсеров, поддерживает XSLT и возможность работать с DTD.
[к оглавлению](#xml)
## Что такое _XSLT_?
__XSLT, eXtensible Stylesheet Language Transformations__ — язык преобразования XML-документов.
XSLT создавался для применения в _XSL (eXtensible Stylesheet Language)_ - языке стилей для XML. Во время XSL-преобразования XSLT-процессор считывает XML-документ и таблицу(ы) стилей XSLT. На основе инструкций, которые процессор находит в таблице(ах) стилей XSLT, он вырабатывает новый XML-документ или его фрагмент.
[к оглавлению](#xml)
# Источники
+ [Википедия](https://ru.wikipedia.org/wiki/XML)
+ [CIT Forum](http://citforum.ru/internet/xnamsps/index.shtml#ns-decl)
+ [Quizful](http://www.quizful.net/interview/java/xml-and-parsers)
[Вопросы для собеседования](README.md)

@ -0,0 +1,221 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# Алгоритмы
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [Алгоритмы](#алгоритмы)
- [Big O](#big-o)
- [ArrayList vs LinkedList](#arraylist-vs-linkedlist)
- [Устройство HashMap](#устройство-hashmap)
- [Рекурсия](#рекурсия)
- [Рекурсия vs Iterator](#рекурсия-vs-iterator)
- [Виды сортировок и их сравнение](#виды-сортировок-и-их-сравнение)
- [Виды поиска и их сравнение](#виды-поиска-и-их-сравнение)
- [Жадный алгоритм](#жадный-алгоритм)
- [Queue, Deque, Stack, Heap](#queue-deque-stack-heap)
- [EnumSet](#enumset)
- [Бинарное дерево](#бинарное-дерево)
- [Красно-черное дерево](#красно-черное-дерево)
- [Мемоизация](#мемоизация)
## Big O
Концепция Big O показывает, какое количество шагов (тактов процессора) необходимо сделать, чтобы полностью завершить алгоритм.
Big O показывает верхную границу ависимости между входными параметрами функции_ и оличеством операций_, которые выполнит процессор. Т.е. описывается только скорость роста функции. Если алгоритм описывается как O(2N), он все равно будет O(n), посколько константы можно отбросить. Не важно, сколько раз будет повторятся алгоритм - бесконечность (n) или две бесконечности (2n) - это все равно будет бесконечность.
Концепция Big O помогает видеть и исправлять неоптимальный код.
```java
время
.
/ \ /
| /
| / O(n)
| /
| /
| /
| /
|-/------------------- O(1)
|/
|
o——————————————————>
кол-во бит
```
__O(n)__ - Больше байт - дольше передавать. Зависимость от количества элементов. В функции это кол-во вызовов функции внутри себя
__О(1)__ - Размер файла не важен, скорость постоянна
__Рекурсивная функция:__ функция вызывает сама себя. Чем больше n, тем больше раз функция вызовет сама себя.
```java
int sum(int n) {
if (n == 1) return 1;
return n + sum(n - 1);
}
```
__Линейная функция:__ кол-во выполнений функции зависит от n.
```java
int pairSunSequence(int n) {
int sum = 0:
for (int i = 0; i < n; i++) {
sum += pairSum(i, i + 1);
}
return sum;
}
int pairSum(int a, int b) {
return a + b;
}
```
__Отбрасывание неважной сложности:__ если одно значение n значительно (в 2 раза) меньше другого значения n^2, то меньшуу n можно отбросить, т.к. она слабо влияет на рост скорости фукнции.
O(n^2 + n) = O(n^2)
O(n + log n) = O(n), т.к log(n) меньше n
O(5 * 2^n + 10 * n^100) = O(2^n)
O(n^2 + b) = O(n^2 + b), мы не может упростить, пока ничего не знаем о b. Оно может быть <, > или = n
__Сложение и умножение сложностей__: Если функции вызываются последовательно, то сложности складываются (они не зависят друг от друга). Если функции выполняются одна в другой (зависят друг от друга) то сложности умножаются.
__Log n__ - для алгоритма, где на каждой итерации берется половина элементов - сложность будет включать O(log n).
## ArrayList vs LinkedList
Класс Получение Поиск Вставка Удаление
ArrayList O(1) O(n) O(n) / O(1) O(n)
LinkedList O(n) O(n) O(1) O(1)
__ArrayList__ реализован внутри в виде обычного массива. Поэтому при вставке элемента в середину, приходится сначала сдвигать на один все элементы после него, а уже затем в освободившееся место вставлять новый элемент. ОДНАКО вставка в конец списка в среднем производится так же за постоянное время. В среднем потому, что массив имеет определенный начальный размер n (в коде это параметр capacity), по умолчанию n = 10, при записи n+1 элемента, будет создан новый массив размером (n * 3) / 2 + 1, в него будут помещены все элементы из старого массива + новый, добавляемый элемент. В итоге получаем, что при добавлении элемента при необходимости расширения массива, время добавления будет значительно больше, нежели при записи элемента в готовую пустую ячейку. Удаление последнего элемента происходит за константное время.
Зато в нем быстро реализованы взятие и изменение элемента операции get, set, так как в них мы просто обращаемся к соответствующему элементу массива.
__LinkedList__ реализован в виде двусвязного списка: набора отдельных элементов, каждый из которых хранит ссылку на следующий и предыдущий элементы. Чтобы вставить элемент в середину такого списка, достаточно поменять ссылки его будущих соседей. А вот чтобы получить элемент с номером 130, нужно пройтись последовательно по всем объектам от 0 до 130. Другими словами операции set и get тут реализованы очень медленно.
Если вставлять (или удалять) в середину коллекции много элементов, то лучше использовать LinkedList. Во всех остальных случаях ArrayList. LinkedList занимает в памяти разрозненные ячейки, а значения ArrayList в памяти хранятся единым массивом.
## Устройство HashMap
HashMap — основан на хэш-таблицах, реализует интерфейс Map (что подразумевает хранение данных в виде пар ключ/значение). Ключи и значения могут быть любых типов, в том числе и null.
Внутри HashMap содержатся массив Bucket (по умолчанию их 16, коэфицент заполнения 0,75 - указывает, когда нужно увеличить массив бакетов). Они используется для хранения узлов (Nodes). Два или более узла могут иметь один и тот-же bucket.
Node представляет класс, содержащий следующие объекты:
+ int — хэш
+ K — ключ
+ V — значение
+ Next — следующий элемент
При добавление ключ-значения в хешмапу проверяем существует ли ключ. Если ключ не существует (null), значение помещается в таблицу на нулевую позицию, потому что хеш-код для значения null, это всегда 0. Дальше высчитывается хеш-код ключа. Ключ делится на количество бакетов, остаток от деления будет номером бакета, куда кладется этот ключ-значение. Ключ-значение оборачивается в Node. Если Node добавляется в бакет, в котором уже есть другая Node, они сравнивают ключи по hashCode() и equals(). Если ключи идентичны - перезаписываются, если нет - новая Node добавляется в начало цепочки и в ней создается ссылка на старую Node и они образуют односвязный список. При этом если Node будут записываться только в один бакет, хешмапа выродится в связный список.
__Изменения в Java 8__
Как мы уже знаем в случае возникновения коллизий объект node сохраняется в структуре данных "связанный список" и метод equals() используется для сравнения ключей. Это сравнения для поиска верного ключа в связанном списке -линейная операция и в худшем случае сложность равнa O(n). Для исправления этой проблемы в Java 8 после достижения определенного порога (__если в бакете >= 7 эелементов, а самих бакетов меньше 64__. иначе вместо перехода к древовидной структуре будет вызван метод resize() для увеличения размера хеш-таблицы с перераспределением элементов.) Вместо связанных списков используются сбалансированные деревья. Это означает, что HashMap в начале сохраняет объекты в связанном списке, но после того, как колличество элементов в хэше достигает определенного порога происходит переход к сбалансированным деревьям. Что улучшает производительность в худшем случае с O(n) до O(log n).
__В итоге__
+ Добавление элемента выполняется за время O(1), потому как новые элементы вставляются в начало цепочки;
+ Операции получения и удаления элемента могут выполняться за время O(1), если хэш-функция равномерно распределяет элементы и отсутствуют коллизии. Среднее же время работы будет Θ(1 + α), где α — коэффициент загрузки. В самом худшем случае, время выполнения может составить Θ(n) (все элементы в одной цепочке);
## Рекурсия
Рекурсия - метод вызывает сам себя, но может вернуть код другого выражения. Не использует стек.
Хвостовая рекурсия - метод возвращает только сам себя. Используется стек.
Базис рекурсии условие выхода из блока рекурсивных вызовов базисное решение задачи, при условиях, когда нет необходимости вызывать рекурсию.
## Рекурсия vs Iterator
Итератор - реализация класса, рекурсия - реализация методом. Итерируем пока не закончится весь список данных, рекурсия существует пока вызывает сама себя.
Рекурсивный метод работает FILO, а итератор FIFO.
Главное преимущество рекурсивных методов заключается в том, что их можно применять для реализации более простых и понятных вариантов некоторых алгоритмов, чем их итерационные аналоги. Например, алгоритм быстрой сортировки очень трудно реализовать итерационным способом. А некоторые виды алгоритмов, связанных с искусственным интеллектом, легче всего реализовать с помощью рекурсивных решений.
Рекурсия используется в глубинном поиске в бинарных деревьях, а итерация в широком поиске.
## Виды сортировок и их сравнение
Быстрая сортировка - Выбирает из массива элемент, называемый опорным. Это может быть любой из элементов массива. Сравнивает все остальные элементы с опорным и переставить их в массиве так, чтобы разбить массив на два непрерывных отрезка, следующих друг за другом: «элементы меньшие опорного», «равные и большие». Для отрезков «меньших» и «больших» значений выполняет рекурсивно ту же последовательность операций, пока длина отрезка больше единицы. __Сложность алгоритма: в среднем O(n log n), в худшем O(n^2)__
Сортировка пузырьком - простейший, но эффективен он лишь для небольших массивов. __Сложность O(n^2)__. Алгоритм состоит из повторяющихся проходов по сортируемому массиву. За каждый проход элементы последовательно сравниваются попарно и, если порядок в паре неверный, выполняется обмен элементов. Проходы по массиву повторяются {\displaystyle N-1}N-1 раз или до тех пор, пока на очередном проходе не окажется, что обмены больше не нужны, что означает — массив отсортирован. При каждом проходе алгоритма по внутреннему циклу, очередной наибольший элемент массива ставится на своё место в конце массива рядом с предыдущим «наибольшим элементом», а наименьший элемент перемещается на одну позицию к началу массива («всплывает» до нужной позиции, как пузырёк в воде — отсюда и название алгоритма).
Шейкерная сортировка - аналогична пузырьковой, но при движении от конца массива к началу минимальный элемент «всплывает» на первую позицию, а максимальный элемент сдвигается только на одну позицию вправо. Кроме того, если при движении по части массива перестановки не происходят, то эта часть массива уже отсортирована и, следовательно, её можно исключить из рассмотрения. __Сложность O(n^2)__
Сортировка выбором - поиск наименьшего или наибольшего элемента и помещение его в начало или конец упорядоченного списка. __Сложность O(n^2)__
Сортировка вставками - элементы входной последовательности просматриваются по одному, и каждый новый поступивший элемент размещается в подходящее место среди ранее упорядоченных элементов. __Сложность O(n^2)__
Гномья сортировка - похожа на сортировку вставками, но в отличие от последней перед вставкой на нужное место происходит серия обменов, как в сортировке пузырьком. __Сложность O(n^2)__
Сортировка слиянием - упорядочивает списки (или другие структуры данных, доступ к элементам которых можно получать только последовательно, например — потоки) в определённом порядке. Сначала делим список на кусочки (по 1 элементу), затем сравниваем каждый элемент с соседним, сортируем и объединяем. В итоге, все элементы отсортированы и объединены вместе. __Сложность алгоритма:O(n log n)__
## Виды поиска и их сравнение
Линейный - перебор всех значений. O(n)
Бинарный (двоичный) - берем средний элемент из массива. Если искомый элемент не равен этому среднему, продолжаем поиск - если искомый элемент меньше, идем в левую половину массива, если искомый больше - идем в правую половину O(log n). Там тоже берем средний элемент и сравниваем с искомым. И так до тех пор, пока не найдем искомый элемент или пока не останется последний элемент массива. Если последний элемент не равен искомому, то искомого элемента в данном массиве не существует.
Поиск в ширину - описывается итератором: метод обхода дерева, при котором поиск ведется по линии "ширине", то есть сначала вершина дерева, потом все эелементы слева направо на втором уровне, потом на третьем и т.д.
Поиск в глубинну - описывается рекурсивно: перебираем все исходящие из рассматриваемой вершины рёбра. Идем от вершины по ветке д осамого конца, затем проверяем все ответления в ветке снизу в верх. Если вернулись к вершине - перебираем следующую ветку.
Алгоритм Кнута-Морриса-Пратта - поиск подстроки в строке. Создается шаблон, по которому ищется подстрока по префиксу и суфиксу. Время работы алгоритма линейно зависит от объёма входных данных.
Даны образец (строка) S и строка T. Требуется определить индекс, начиная с которого образец S содержится в строке T. Если S не содержится в T — вернуть индекс, который не может быть интерпретирован как позиция в строке (например, отрицательное число).
Префикс-функция(количество повторений) для строки "abcabcd" равна: [0, 0, 0, 1, 2, 3, 0], что означает:
- у строки "a" нет нетривиального префикса, совпадающего с суффиксом;
- у строки "ab" нет нетривиального префикса, совпадающего с суффиксом;
- у строки "abc" нет нетривиального префикса, совпадающего с суффиксом;
- у строки "abca" префикс длины 1 совпадает с суффиксом;
- у строки "abcab" префикс длины 2 совпадает с суффиксом;
- у строки "abcabc" префикс длины 3 совпадает с суффиксом;
- у строки "abcabcd" нет нетривиального префикса, совпадающего с суффиксом.
## Жадный алгоритм
Это алгоритм, который на каждом шагу делает локально наилучший выбор в надежде, что итоговое решение будет оптимальным.
## Queue, Deque, Stack, Heap
Queue (очередь) - предназначена для хранения элементов с предопределённым способом вставки и извлечения FIFO (first-in-first-out). PriorityQueue — предоставляет возможность управлять порядком элементов в коллекции при помощи объекта Comparator, либо сохраняет элементы с использованием «natural ordering»
Deque (Double Ended Queue) расширяет Queue и согласно документации это линейная коллекция, поддерживающая вставку/извлечение элементов с обоих концов. Помимо этого реализации интерфейса Deque могут строится по принципу FIFO, либо LIFO. ArrayDeque — реализация интерфейса Deque, который расширяет интерфейс Queue методами, позволяющими реализовать конструкцию вида LIFO (last-in-first-out)
Stack - предназначена для хранения элементов с предопределённым способом вставки и извлечения FILO, First-In-Last-Out («первым пришел, последним ушел»)
## EnumSet
EnumSet - это реализация интерфейса Set для использования с перечислениями (Enum). В структуре данных хранятся объекты только одного типа Enum, указываемого при создании. Для хранения значений EnumSet использует массив битов (bit vector), - это позволяет получить высокую компактность и эффективность. Проход по EnumSet осуществляется согласно порядку объявления элементов перечисления.
Все основные операции выполняются за O(1) и обычно (но негарантированно) быстрей аналогов из HashSet, а пакетные операции (bulk operations), такие как containsAll() и retainAll() выполняются даже горазда быстрей.
Помимо всего EnumSet предоставляет множество статических методов инициализации для упрощенного и удобного создания экземпляров.
## Бинарное дерево
Упорядоченный граф, у которого имеется корень (вершина) и ветви влево-вправо. в Левую ветвь заносятся значения меньше, чем в корне, в правую ветвь значения больше корня. В ветвях значения так же сортируются, образуя ответвления от ветви.
__Проблема__ - В вырожденном случае может оказаться, что всё левое дерево пусто на каждом уровне, есть только правые деревья, и в таком случае дерево вырождается в список (идущий вправо). Поиск (а значит, и удаление и добавление) в таком дереве по скорости равен поиску в списке и намного медленнее поиска в сбалансированном дереве.
Для балансировки дерева применяется операция «поворот дерева». Для принятия решения о том, какие именно повороты нужно совершать после добавления или удаления, используются такие алгоритмы, как «красно-чёрное дерево».
## Красно-черное дерево
Вид бинарных деревьев, у которых присутствует балансировка - за счет дополнительного атрибута - цвета. Этот атрибут может принимать одно из двух возможных значений — «чёрный» или «красный». КЧД реализованны в TreeMap, TreeSet. При этом:
+ Узел может быть либо красным, либо чёрным и имеет двух потомков;
+ Корень — как правило чёрный. Это правило слабо влияет на работоспособность модели, так как цвет корня всегда можно изменить с красного на чёрный;
+ Все листья — чёрные и не содержат данных. Для экономии памяти листья можно сделать одним общим фиктивным листом.
+ Оба потомка каждого красного узла — чёрные.
+ Любой простой путь от узла-предка до листового узла-потомка содержит одинаковое число чёрных узлов.
Красно-чёрные деревья более популярны, чем идеально сбалансированные деревья, т.к. в последних может тратиться слишком много ресурсов на операции удаления из дерева и поддержание необходимой сбалансированности.
## Мемоизация
Сохранение результатов выполнения функций для предотвращения повторных вычислений. Перед вызовом функции проверяется, вызывалась ли функция ранее: если не вызывалась, то функция вызывается, и результат её выполнения сохраняется; а если вызывалась, то используется сохранённый результат.

@ -0,0 +1,481 @@
# Cобеседование по Java. Разбор вопросов и ответов.
<a href="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%">
<img src="https://mc.yandex.ru/pixel/8711235002931986822?rnd=%aw_random%" />
</a>&nbsp;&nbsp;
<a href="https://mc.yandex.ru/watch/92801430">
<img src="https://mc.yandex.ru/watch/92801430" />
</a>&nbsp;&nbsp;
Нажмите ★, если вам нравится проект. Ваш вклад сердечно ♡ приветствуется.
Если вам интересно мое резюме: https://github.com/DEBAGanov
# ООП + Микросервисы
- [Cобеседование по Java. Разбор вопросов и ответов.](#cобеседование-по-java-разбор-вопросов-и-ответов)
- [ООП + Микросервисы](#ооп--микросервисы)
- [Что такое _ООП_?](#что-такое-ооп)
- [Назовите основные принципы _ООП_.](#назовите-основные-принципы-ооп)
- [Что такое _«инкапсуляция»_?](#что-такое-инкапсуляция)
- [Что такое _«наследование»_?](#что-такое-наследование)
- [Что такое _«полиморфизм»_?](#что-такое-полиморфизм)
- [Что такое _«абстракция»_?](#что-такое-абстракция)
- [Что представляет собой _«обмен сообщениями»_?](#что-представляет-собой-обмен-сообщениями)
- [Расскажите про основные понятия ООП: _«класс»_, _«объект»_, _«интерфейс»_.](#расскажите-про-основные-понятия-ооп-класс-объект-интерфейс)
- [В чем заключаются преимущества и недостатки объектно-ориентированного подхода в программировании?](#в-чем-заключаются-преимущества-и-недостатки-объектно-ориентированного-подхода-в-программировании)
- [Что подразумевают в плане принципов ООП выражения _«является»_ и _«имеет»_?](#что-подразумевают-в-плане-принципов-ооп-выражения-является-и-имеет)
- [В чем разница между _композицией_ и _агрегацией_?](#в-чем-разница-между-композицией-и-агрегацией)
- [Что такое _статическое_ и _динамическое связывание_?](#что-такое-статическое-и-динамическое-связывание)
- [Принцип SOLID?](#принцип-solid)
- [Что такое Монолит, Микросервис?](#что-такое-монолит-микросервис)
- [Что выбрать Монолит или Микросервис?](#что-выбрать-монолит-или-микросервис)
- [Взаимодействие между микросервисами](#взаимодействие-между-микросервисами)
- [OpenAPI](#openapi)
- [Тестирование микросервисов](#тестирование-микросервисов)
- [Распределенная трассировка](#распределенная-трассировка)
- [Источники](#источники)
## Что такое _ООП_?
__Объектно-ориентированное программирование (ООП)__ — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.
+ объектно-ориентированное программирование использует в качестве основных логических конструктивных элементов объекты, а не алгоритмы;
+ каждый объект является экземпляром определенного класса
+ классы образуют иерархии.
Программа считается объектно-ориентированной, только если выполнены все три указанных требования. В частности, программирование, не использующее наследование, называется не объектно-ориентированным, а программированием с помощью абстрактных типов данных.
Согласно парадигме ООП программа состоит из объектов, обменивающихся сообщениями. Объекты могут обладать состоянием, единственный способ изменить состояние объекта - послать ему сообщение, в ответ на которое, объект может изменить собственное состояние.
[к оглавлению](#ООП)
## Назовите основные принципы _ООП_.
+ _Инкапсуляция_ - сокрытие реализации.
+ _Наследование_ - создание новой сущности на базе уже существующей.
+ олиморфизм_ - возможность иметь разные формы для одной и той же сущности.
+ _Абстракция_ - набор общих характеристик.
+ осылка сообщений_ - форма связи, взаимодействия между сущностями.
+ ереиспользование_- все что перечислено выше работает на повторное использование кода.
Это единственно верный порядок парадигм ООП, так как каждая последующая использует предыдущие.
[к оглавлению](#ООП)
## Что такое _«инкапсуляция»_?
__Инкапсуляция__ это свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе и скрыть детали реализации от пользователя, открыв только то, что необходимо при последующем использовании.
Цель инкапсуляции — уйти от зависимости внешнего интерфейса класса (то, что могут использовать другие классы) от реализации. Чтобы малейшее изменение в классе не влекло за собой изменение внешнего поведения класса.
[к оглавлению](#ООП)
## Что такое _«наследование»_?
__Наследование__ это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью.
Класс, от которого производится наследование, называется _предком_, _базовым_ или _родительским_. Новый класс _потомком_, аследником_ или _производным_ классом.
[к оглавлению](#ООП)
## Что такое _«полиморфизм»_?
__Полиморфизм__ это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Преимуществом полиморфизма является то, что он помогает снижать сложность программ, разрешая использование одного и того же интерфейса для задания единого набора действий. Выбор же конкретного действия, в зависимости от ситуации, возлагается на компилятор языка программирования. Отсюда следует ключевая особенность полиморфизма - использование объекта производного класса, вместо объекта базового (потомки могут изменять родительское поведение, даже если обращение к ним будет производиться по ссылке родительского типа).
Полиморфизм бывает _динамическим_ (переопределение) и _статическим_ (перегрузка).
олиморфная переменная_, это переменная, которая может принимать значения разных типов, а _полиморфная функция_, это функция у которой хотя бы один аргумент является полиморфной переменной.
Выделяют два вида полиморфных функций:
+ _ad hoc_, функция ведет себя по разному для разных типов аргументов (например, функция `draw()` — рисует по разному фигуры разных типов);
+ _параметрический_, функция ведет себя одинаково для аргументов разных типов (например, функция `add()` — одинаково кладет в контейнер элементы разных типов).
[к оглавлению](#ООП)
## Что такое абстракция»_?
_Абстрагирование_ это способ выделить набор общих характеристик объекта, исключая из рассмотрения частные и незначимые. Соответственно, __абстракция__ это набор всех таких характеристик.
[к оглавлению](#ООП)
## Что представляет собой обмен сообщениями»_?
Объекты взаимодействуют, посылая и получая сообщения. Сообщение — это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия. В ООП посылка сообщения (вызов метода) — это единственный путь передать управление объекту. Если объект должен «отвечать» на это сообщение, то у него должна иметься соответствующий данному сообщению метод. Так же объекты, используя свои методы, могут и сами посылать сообщения другим объектам. Обмен сообщениями реализуется с помощью динамических вызовов, что приводит к чрезвычайно позднему связыванию (extreme late binding).
[к оглавлению](#ООП)
## Расскажите про основные понятия ООП: _«класс»_, объект»_, _«интерфейс»_.
__Класс__ это способ описания сущности, определяющий состояние и поведение, зависящее от этого состояния, а также правила для взаимодействия с данной сущностью (контракт).
С точки зрения программирования класс можно рассматривать как набор данных (полей, атрибутов, членов класса) и функций для работы с ними (методов).
С точки зрения структуры программы, класс является сложным типом данных.
__Объект (экземпляр)__ это отдельный представитель класса, имеющий конкретное состояние и поведение, полностью определяемое классом. Каждый объект имеет конкретные значения атрибутов и методы, работающие с этими значениями на основе правил, заданных в классе.
__Интерфейс__ это набор методов класса, доступных для использования. Интерфейсом класса будет являться набор всех его публичных методов в совокупности с набором публичных атрибутов. По сути, интерфейс специфицирует класс, чётко определяя все возможные действия над ним.
[к оглавлению](#ООП)
## В чем заключаются преимущества и недостатки объектно-ориентированного подхода в программировании?
Преимущества:
+ Объектная модель вполне естественна, поскольку в первую очередь ориентирована на человеческое восприятие мира, а не на компьютерную реализацию.
+ Классы позволяют проводить конструирование из полезных компонентов, обладающих простыми инструментами, что позволяет абстрагироваться от деталей реализации.
+ Данные и операции над ними образуют определенную сущность, и они не разносятся по всей программе, как нередко бывает в случае процедурного программирования, а описываются вместе. Локализация кода и данных улучшает наглядность и удобство сопровождения программного обеспечения.
+ Инкапсуляция позволяет привнести свойство модульности, что облегчает распараллеливание выполнения задачи между несколькими исполнителями и обновление версий отдельных компонентов.
+ Возможность создавать расширяемые системы.
+ Использование полиморфизма оказывается полезным при:
+ Обработке разнородных структур данных. Программы могут работать, не различая вида объектов, что существенно упрощает код. Новые виды могут быть добавлены в любой момент.
+ Изменении поведения во время исполнения. На этапе исполнения один объект может быть заменен другим, что позволяет легко, без изменения кода, адаптировать алгоритм в зависимости от того, какой используется объект.
+ Реализации работы с наследниками. Алгоритмы можно обобщить настолько, что они уже смогут работать более чем с одним видом объектов.
+ Возможности описать независимые от приложения части предметной области в виде набора универсальных классов, или фреймворка, который в дальнейшем будет расширен за счет добавления частей, специфичных для конкретного приложения.
+ Повторное использование кода:
+ Сокращается время на разработку, которое может быть отдано другим задачам.
+ Компоненты многоразового использования обычно содержат гораздо меньше ошибок, чем вновь разработанные, ведь они уже не раз подвергались проверке.
+ Когда некий компонент используется сразу несколькими клиентами, улучшения, вносимые в его код, одновременно оказывают положительное влияние и на множество работающих с ним программ.
+ Если программа опирается на стандартные компоненты, ее структура и пользовательский интерфейс становятся более унифицированными, что облегчает ее понимание и упрощает использование.
Недостатки:
+ В сложных иерархиях классов поля и методы обычно наследуются с разных уровней. И не всегда легко определить, какие поля и методы фактически относятся к данному классу.
+ Код для обработки сообщения иногда «размазан» по многим методам (иначе говоря, обработка сообщения требует не одного, а многих методов, которые могут быть описаны в разных классах).
+ Документирование классов - задача более трудная, чем это было в случае процедур и модулей. Поскольку любой метод может быть переопределен, в документации должно говориться не только о том, что делает данный метод, но и о том, в каком контексте он вызывается.
+ Неэффективность и неэкономное распределения памяти на этапе выполнения (по причине издержек на динамическое связывание и проверки типов на этапе выполнения).
+ Излишняя универсальность. Часто содержится больше методов, чем это реально необходимо текущей программе. А поскольку лишние методы не могут быть удалены, они становятся мертвым грузом.
[к оглавлению](#ООП)
## Что подразумевают в плане принципов ООП выражения _«является»_ и _«имеет»_?
__«является»__ подразумевает наследование.
__«имеет»__ подразумевает ассоциацию (агрегацию или композицию).
[к оглавлению](#ООП)
## В чем разница между омпозицией_ и _агрегацией_?
Ассоциация обозначает связь между объектами. Композиция и агрегация — частные случаи ассоциации «часть-целое».
Агрегация предполагает, что объекты связаны взаимоотношением «part-of» (часть). Композиция более строгий вариант агрегации. Дополнительно к требованию «part-of» накладывается условие, что экземпляр «части» может входить только в одно целое (или никуда не входить), в то время как в случае агрегации экземпляр «части» может входить в несколько целых.
>Например, книга состоит из страниц и мы не можем вырвать страницу из книги и вложить в другую книгу. Страницы четко привязаны к конкретной книге, поэтому это композиция.
В тоже время мы можем взять и перенести книгу из одной библиотеки в другую - это уже агрегация.
[к оглавлению](#ООП)
## Что такое _статическое_ и _динамическое связывание_?
Связывание означает наличие связи между ссылкой и кодом. Например, переменная, на которую вы ссылаетесь, привязана к коду, в котором она определена. Аналогично, вызываемый метод привязан к месту в коде, где он определен. Присоединение вызова метода к телу метода. Если связывание проводится компилятором (компоновщиком) перед запуском программы, то оно называется _статическим_ или _ранним связыванием (early binding)_.
В свою очередь, _позднее связывание (late binding)_ это связывание, проводимое непосредственно во время выполнения программы, в зависимости от типа объекта. Позднее связывание также называют _динамическим (dynamic)_ или _связыванием на стадии выполнения (runtime binding)_. В языках, реализующих позднее связывание, должен существовать механизм определения фактического типа объекта во время работы программы, для вызова подходящего метода. Иначе говоря, компилятор не знает тип объекта, но механизм вызова методов определяет его и вызывает соответствующее тело метода. Механизм позднего связывания зависит от конкретного языка, но нетрудно предположить, что для его реализации в объекты должна включаться какая-то дополнительная информация.
Итак, фундаментальное различие между статическим и динамическим связыванием в Java состоит в том, что первое происходит рано, во время компиляции на основе типа ссылочной переменной, а второе позднее, во время выполнения, с использованием конкретных объектов.
Для всех методов Java используется механизм позднего (динамического) связывания, если только метод не был объявлен как `static` или `final` (приватные методы являются `final` по умолчанию).
Ключевые различия между ранним и поздним связыванием в языке Java:
1) Статическое связывание происходит во время компиляции, а динамическое во время выполнения.
2) Поскольку статическое связывание происходит на ранней стадии жизненного цикла программы, его называют ранним связыванием. Аналогично, динамическое связывание называют также поздним связыванием, поскольку оно происходит позже, во время работы программы.
3) Статическое связывание используется в языке Java для разрешения перегруженных методов, в то время как динамическое связывание используется в языке Java для разрешения переопределенных методов.
4) Аналогично, приватные, статические и терминальные методы разрешаются при помощи статического связывания, поскольку их нельзя переопределять, а все виртуальные методы разрешаются при помощи динамического связывания.
5) В случае статического связывания используются не конкретные объекты, а информация о типе, то есть для обнаружения нужного метода используется тип ссылочной переменной. С другой стороны, при динамическом связывании для нахождения нужного метода в Java используется конкретный объект.
[к оглавлению](#ООП)
## Принцип SOLID?
Пять основных принципов дизайна классов:
+ Single Responsibility Principle (Принцип единственной ответственности).
+ Open Closed Principle (Принцип открытости/закрытости).
+ Liskovs Substitution Principle (Принцип подстановки Барбары Лисков).
+ Interface Segregation Principle (Принцип разделения интерфейса).
+ Dependency Inversion Principle (Принцип инверсии зависимостей).
__Принцип единственной ответственности (SRP)__ <br>
Никогда не должно быть больше одной причины изменить класс.
Класс должен быть ответственен лишь за что-то одно. Если класс отвечает за решение нескольких задач, его подсистемы, реализующие решение этих задач, оказываются связанными друг с другом. Изменения в одной такой подсистеме ведут к изменениям в другой.
Представьте себе модуль, который обрабатывает заказы. Если заказ верно сформирован, он сохраняет его в базу данных и высылает письмо для подтверждения заказа. Принцип единственной обязанности подразумевает, что три аспекта этой проблемы на самом деле — три разные обязанности. А значит, должны находиться в разных классах или модулях. Объединение нескольких сущностей, которые могут меняться в разное время и по разным причинам, считается плохим проектным решением. Гораздо лучше разделить модуль на три отдельных, каждый из которых будет выполнять одну единственную функцию.
__Принцип открытости/закрытости (OCP)__<br>
Программные сущности (классы, модули, функции и т.п.) должны быть открыты для расширения, но закрыты для изменения.
Это означает, что должна быть возможность изменять внешнее поведение класса, не внося физические изменения в сам класс. Следуя этому принципу, классы разрабатываются так, чтобы для подстройки класса к конкретным условиям применения было достаточно расширить его и переопределить некоторые функции. Поэтому система должна быть гибкой, с возможностью работы в переменных условиях без изменения исходного кода. Используются интерфейсы
__Принцип подстановки Барбары Лисков (LSP)__<br>
Объекты в программе можно заменить их наследниками без изменения свойств программы.
Это означает, что класс, разработанный путем расширения на основании базового класса, должен переопределять его методы так, чтобы не нарушалась функциональность с точки зрения клиента. То есть, если разработчик расширяет ваш класс и использует его в приложении, он не должен изменять ожидаемое поведение переопределенных методов. Если оказывается, что в коде проверяется тип класса, значит принцип подстановки нарушается.
__Принцип разделения интерфейса (ISP)__<br>
Клиенты не должны быть вынуждены реализовывать методы, которые они не будут использовать.
Принцип разделения интерфейсов говорит о том, что слишком «толстые» интерфейсы необходимо разделять на более мелкие и специфические, чтобы клиенты мелких интерфейсов знали только о методах, необходимых в работе.
Рассмотрим пример. Разработчик Алекс создал интерфейс "отчет" и добавил два метода: generateExcel() и generatedPdf(). Теперь клиент А хочет использовать этот интерфейс, но он намерен использовать отчеты только в PDF-формате, а не в Excel. Он должен будет реализовать два метода, один из которых по большому счету не нужен и существует только благодаря Алексу — дизайнеру программного обеспечения. Клиент воспользуется либо другим интерфейсом, либо оставит поле для Excel пустым. Так в чем же решение? Оно состоит в разделении существующего интерфейса на два более мелких. Один — отчет в формате PDF, второй — отчет в формате Excel. Это даст пользователю возможность использовать только необходимый для него функционал.
__Принцип инверсии зависимостей (DIP)__<br>
Зависимости внутри системы строятся на основе абстракций. Объектом зависимости должна быть абстракция, а не что-то конкретное. Модули верхнего уровня не зависят от модулей нижнего уровня. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций. Программное обеспечение нужно разрабатывать так, чтобы различные модули были автономными и соединялись друг с другом с помощью абстракции.
Классическое применение этого принципа — Spring framework. В рамках Spring framework все модули выполнены в виде отдельных компонентов, которые могут работать вместе. Они настолько автономны, что могут быть быть с такой же легкостью задействованы в других программных модулях помимо Spring framework. Это достигнуто за счет зависимости закрытых и открытых принципов. Все модули предоставляют доступ только к абстракции, которая может использоваться в другом модуле.
[к оглавлению](#ООП)
## Что такое Монолит, Микросервис?
Монолитная архитектура - система с одним сервисом, который отвечает за работу со всей предметной областью бизнеса (приложения)
При начале работы над монолитным проектом Достоинства:
+ Быстрая разработка
+ Возможность внесения радикальных изменений (например изменить архитетуру, класс-дизайн, схему бд)
+ Безболезненое тестирование
+ Легкое развертывание
+ Простое hardware масштабирование
С увеличением размера проекта и команды разработки появляются Минусы:
+ Медленное внесение изменений
Команды А и Б работают не пересекаясь. Выкатывается новая версия проекта с багами в коде команды Б. Откатывается на предыдущуюю версию весь код и команды Б и команды А.
+ Уязвимая надежность - если падает часть кода, то не работает все приложение.
+ Трудности в hardware масштабировании.
Одна часть требует оперативу, другая ядра. Приходится апгрейдить "вертикально" - покупать больше оперативных планок и процессоры с большим кол-вом ядер для всех сервисов. А не по потребностям
+ Дороговизна обновления технологического стека
Например переход на новую версию Java. Чтобы проверить эффективность, нужно переписывать весь проект
Микросервисная архитектура — система, которая содержит больше одного обособленнго сервиса. Размер значения не имеет.
Обособленный сервис — является независимой единицей развертывания, имеет своё хранилище, свою БД (?), отвечает за свою часть предметной области
Достоинства:
+ Возможность масштабирования разработки
+ Дешевизна эксперементов с новым стеком
+ Инкрементальное обновление технолошического стека
+ Повышенная надежность и отказоустойчивость
Минусы:
+ Сложность проектирования архитектуры
+ Долгое внесение радикальных изменений
+ Нетривиальное тестирование
+ Повышенные требования к Continuous Integration/Continuous Delivery (деплою)
Непрерывная интеграция (CI) — процесс автоматического принятия изменений. Первичный процесс обновления ПО, в рамках которого все изменения на уровне кода вносятся в единый центральный репозиторий. Такое внесение принято называть слиянием. После каждого слияния (которое проходит по несколько раз в день) в изменяемой системе происходит автоматическая сборка (часто приложение упаковывается в Docker) и тестирование (проверка конкретных модулей кода, UI, производительности, надёжности API). Таким образом разработчики страхуются от слишком поздних обнаружений проблем в обновлениях.
+ Возможность локальной сборки проекта
+ На каждый коммит в кдаленный репо запускаем сборки проекта в системе (Jenkins, TravisCI)
+ Сломанная сборка запрещает слияние
Непрерывная доставка (CD) — CI + CD. Автоматизированый процесс доставки изменений до продакшена. Теперь новая версия не только создаётся и тестируется при каждом изменении кода, регистрируемом в репозитории, но и может быть оперативно запущена по одному нажатию кнопки развёртывания. Однако запуск развёртывания всё ещё происходит вручную — ту самую кнопку всё же надо кому-то нажать. Этот метод позволяет выпускать изменения небольшими партиями, которые легко изменить или устранить в случае необходимости.
+ Поддерживаем артефакты стабильными
+ Развертываем по кнопке
Сложности проектирования Микросервисов
+ Сложно разделить предметную область на части
Не стоит делить монолит на микросервисы по функциональным возможностям. Это приведет к распределенному монолиту - архитектура, включающая недостатки и того и другого. Монолит нужно разбивать по пренадлежности к какой-то области бизнеса. Отличить одно от другого довольно сложно. Т.е. по принципу единой ответственности.
Соответствие принципам Low coupling, high cohesion способствует быстрому внесению изменений и легкому тетсированию.
Сильная связанность high cohesion - части системы, которые изменяются вместе, должны находиться ближе друг к другу
Слабая связанность low coupling - части системы, которые изменяются параллельно, должны иметь как можно меньше зависимостей друг на друга
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP1.png)
И внутри сервиса и между сервисами
+ Задержки при межсервисном взаимодействии влияют на производительность + сеть ненадежна
+ Межсервисное взаимодействие влияет на доступность
+ Сложно добиться согласованности данных
[к оглавлению](#ООП)
## Что выбрать Монолит или Микросервис?
Микро если:
+ Предметная область хорошо делится на части
+ Много направлений, которые нужно развивать параллельно
+ "Особенности" монолита не устраивают бизнес
Монолит если:
+ Нужно быстро сделать прототип
+ Вашу задачу можно решить одним сервисом
+ Непонятно, как разделить предметную область
+ Низкие нагрузки, мало разработчиков, нет ресурсов на поддержание микросервисов
https://microservices.io/
https://martinfowler.com/
"microservices patterns" chris richardson
"clean architecture" robert martin
[к оглавлению](#ООП)
## Взаимодействие между микросервисами
Межсервисное взаимодействие = сетевое взаимодействие, т.е. система управляется сообщениями
+ Производительность = задержки и пропускная способность
+ Доступность и отказоустойчивость
+ Архитектура
_Транспорт_
+ стандарт JSON внутри HTTP
HTTP - простой, множество инструментов, человекочитаемость. Из-за текстового формата большие объемы и нужно оптимизировать
+ бинарные протоколы: gRPC, Thrift, Avro и т.д.
Выше производительность, оптимизированно представление данных, можно определить схему сообщения из коробки, но меньше инструментов и не читаемы человеком
Что выбрать?
+ Начинать с HTTP
+ Бинарные не бесплатные
+ Большинство проблем не из-за протокола
+ Для публичных API всегда HTTP либо несколько реализаций одна из которых HTTP
_API_
Application Programming Interface - интерфейс, определяющий способ и схему взаимодействия с сервисом
+ Remote Procedure Call (RPC)
Только POST метод. Все параметры в теле запроса. Любой статус !=200, считается ошибкой
Выбирают: Простая реализация, Внутренние API, HTTP только как транспорт
+ Representational State Transfer (REST)
Архитектурный стиль, в основе которого лежат ресурсы и их идентификация, изменение их состояния через представление. REST != HTTP
Выбирают: Своего рода стандарт, Внутренние API, Публичные API, HTTP как протокол
+ GraphQL
Язык запросов для API. Например можно задать конкретный набор полей, которые хотим получить в ответе на запрос
Выбирают: Типо-безопасность, API для Web и мобильных клиентов, тут свой инструментарий
Проектирвоание
+ Клиент-сервер
+ Stateless - сервис не должен хранить состояние в памяти, это важно для масштабирования
+ Кеширование
__Типы сообщений__
+ Команды
Императивное управление (звучит как "сделать что-то"), вызывают сильную связанность, зато понятны - названия обычно отражают логику
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP2.png)
+ События
Декларативное управление (звучит как "что-то произошло"), снижают связанность, менее понятны - не знаем что скрыто в notifyOrderCreated
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP3.png)
__Виды взаимодействия__
+ Синхронные - отправляем запрос и блокируемся, ожидая результата.
Просто и понятно, быстрые операции и низкие задержки (ок), низкая пропускная способность (не ок), вызывает низкую доступность (не ок)
+ Ассинхронные - не блокируемся ожидая ответ
Сложнее в реализации, выше задержки (не ок), выше пропускная способность (ок), повышает доступность (ок)
Short polling - вызываем операцию и получаем ссылку на ресурс с результатом операции. Переодически опрашиваем этот ресурс на предмет текущего статуса операции
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP4.png)
Пользователь должен ждать как можно меньше, и нужно выполнять как можно меньше запросов на опрос
Стратегии опроса:
+ Фиксированное время (раз в секунду) - просто, но время запроса может чуть отличаться, что приведет к лишним запросам
+ Прогрессия (геометрическая/алгебраическая) - сокращает кол-во запросов, но возможен вариант когда придется долго ждать
+ На основе статистического распределения - например, знаем, что запрос выполняется 50% за 1.5с, 90% за 3с и 99% за 5с, мы можем распределить запросы во времени
Callbacks - вызываем операцию и получаем идентификатор операции. Сервис, выполняющий операцию, отправляет уведомление вызвавшему сервису о результате выплонения операции
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP5.png)
__Способы взаимодействия__
+ Прямой обмен А->Б - просто, легкая эксплуатация, но сильная связанность сервисов. Хорошо для Команд
+ Обмен через брокеры сообщений А->Брокер->Б - сложнее, позволяет снизить связанность сервисов. Хорошо для Событий
На основе callback: RabbitMQ
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP6.png)
На основе polling: Kafka
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP7.png)
Микросервисы могут работать одновеременно с разными диалектами БД. При этом есть __сильная согласованность__, когда изменения сразу видны всем, с момента их применения и __конечная согласованность__ когда изменения будут видно, но не сразу, а доставляются асинхронно
__Сильная согласованность__ - всегда актуальные данные, но высокие задержки при получении
В таких случаях используются __Распределенные транзакции__. Но это сложно, дорого и есть не везде. Можно эмулировать распределенную транзакцию с помощью вложенных локальных транзакций
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP8.png)
При этом возврат ошибки не гарантирует, что запись не была вставленна в БД. А откат первой транзакции не приводит к откату второй.
Saga паттерн: Для решения нужно разбивать одну большую распределенную транзакцию на последовательность локальных транзакций и предоставить возможность отката всех локальных транзакций.
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP9.png)
Особенности: нужно уметь восстанавливаться после сбоев любого участка и повторять сагу с определенного шага + отличать финальные ошибки от нефинальных
Хореография
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP10.png)
+ Нет единой точки отказа
+ Легко менять кусочек процесса
+ Сложно понять процесс целиком и отслеживать ошибки
Оркестрация
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP11.png)
+ Есть единая точка отказа
+ Сложнее вносить изменения в места
+ Легко понять процесс и отслеживать ошибки
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP12.png)
__Конечная согласованность__ - могут быть неактуальные данные, зато низкие задержки
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP13.png)
__Взаимоисключения__
Иногда требуется выполнять какой-то процесс эксклюзивно. Например используя распределенный консенсус - алгоритмы, которые сложно и медленно работают. etcd, Consul, Zookeeper. Зато отказоустойчивы
Альтернатива - red lock, когда БД используется в качестве хранилища блокировок. Блокировка не захватывается, а арендуется на время. Чтобы в случае блокировки и отказа системы блокировка не осталась навсегда Добавляем версию блокировки для контроля ее корректности
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP14.png)
[к оглавлению](#ООП)
## OpenAPI
OpenAPI - спецификация для описания REST API.
https://habr.com/ru/post/541592/
Swagger - это фреймворк для спецификации RESTful API, цель которого - поддерживать документацию в актуальном виде. Его прелесть заключается в том, что он дает возможность не только интерактивно просматривать спецификацию, но и отправлять запросы так называемый Swagger UI.
+ Code first - сначала пишем код, потом генерируем спецификацию
+ Schema first - сперва спецификация, затем генерируем по ней код
+ Публикуем спецификацию (отделный артефак или Swagger)
+ Строго следовать этой спецификации
Документирование БД
Database Schema as a Code - текущая схема должна быть представлена последовательностью патчей, хранимых как код
+ Возможность восстановить БД на любом окружении
+ Аудит, контроль, валидация
+ Flyway, Liquibase
[к оглавлению](#ООП)
## Тестирование микросервисов
+ Компонентные для тестирования логики приложения
+ Модульные для тестирования вычислений
+ Компонентных должно быть больше, чем модульных, т.к. изменяемая среда, много зависимочти между классами
Тесты должны быть независимыми и уметь работать параллельно. Тесты не должны очищать БД или буффер брокера сообщений перед/после своего запуска/завершения
Для тестирования API лучше делать реальные HTTP вызовы, валидировать ответ согласно схеме (JSON). RESTAssured как пример инструмента.
При тестирование взаимодействия с БД на каждый запуск тестов локально поднимается БД. Embedded или TestContainers
При тестировании взаимодействия микросервисов на каждый запуск тестов локально HTTP-сервер, создаем моки операций сервисов, выполняем, моки валидируем. WireMock, MockServer
При тестировании аинхронных процессов стараемся приблизить тестовый сценарий к реальному, запускаем операцию и ждем завершения выполнения. Awaitility
Для автоматизации развиваем Continuous Integration/Continuous Delivery - помогает быстрее развивать сервисы и доставлять их на production. Но дорого.
[к оглавлению](#ООП)
## Распределенная трассировка
При межсервисном взаимодействии сложно отследить весь путь запроса по системе
+ К каждому внешнему запрсос прикрепляем "идентификатор операции"
+ Пробрасываем его по всей системе
+ Добавляем его в логовые сообщения для отслеживания. Elastic APM, OpenTracing
Для HTTP: Прикрепляем HTTP-заголовок с этим идентификатором - Используем его при обработке запроса - Поллинг делаем с тем же индентификаторо - Обраный вызов с ним же - В брокер сообщений также отправляем этот индентификатор
Для Саги: Исходный запрос теряется при обработке асинхронных процессов - В задачу на продолжение саги кладем исходный идентификатор операции (в БД) - При возобновлении саги используем этот идентификатор
Визуализация трасс помогает построить схему взаимодействия между сервисами. Можно это делать атоматически и динамически. Zipkin, Jaeger
[к оглавлению](#ООП)
# Источники
+ [DevColibri](http://devcolibri.com/720)
+ [Хабрахабр](https://habrahabr.ru/post/87119/)
+ [Википедия](https://ru.wikipedia.org/wiki/Объектно-ориентированное_программирование)
[Вопросы для собеседования](README.md)

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

@ -0,0 +1,67 @@
# Шпаргалка по MongoDB
<div align="right"><a href="https://github.com/cheatsnake/backend-cheats#mongodb">Вернуться на главную страницу ⬆️</a></div>
- Подготовка БД
```js
show dbs // показать список всех БД
use db_name // подключиться/создать БД с именем db_name
db // вывести имя текущей базы данных
db.createCollection("users") // создать коллекцию "notes"
show collections // показать список коллекций в текущей БД
db.dropDatabase() // удалить текущую БД
```
- Добавление элементов
```js
// Добавить один элемент
db.users.insertOne({
name: "Alex",
age: 27,
isMarried: false,
city: "NewYork"
})
// Добавить несколько элементов
db.users.insertMany([{...}, {...}])
```
- Получение элементов
```js
// Получить все элементы из коллекции
db.users.find();
// Получить элементы по указанному критерию
db.user.find({ age: 27 });
// Получить один элемент
db.users.findOne({ name: "Alex" });
// Получить отсортированный список элементов
// 1 - по возрастанию; -1 - по убыванию
db.users.find().sort({ age: 1 });
// Получить количество элементов
db.users.find().count();
// Лимит количества получаемых элементов
db.users.find().limit(10);
// Выборка с помощью операторов сравнения
db.users.find({ age: { $gt: 20 } }); // > 20
db.users.find({ age: { $gte: 20 } }); // >= 20
db.users.find({ age: { $lt: 50 } }); // < 50
db.users.find({ age: { $lte: 50 } }); // <= 50
db.users.find({ age: { $ne: 35 } }); // != 35
```
- Изменение элементов
```js
// Полное изменение элемента (первый аргумент - критерий поиска)
db.users.updateOne({name: "Alex"}, {новыеанные})
// Изменение определенных полей элемента
db.users.updateOne({name: "Alex"}, {$set: {age: 28, isMarried: true}})
// Переименовать поле у нескольких элементов
db.users.updateMany({name: "Alex"}, {&rename: {city: "town"}})
// Удаление элемента/элементов
db.users.deleteOne({name: "Alex"})
db.users.deleteMany({name: "Alex"})
```

@ -0,0 +1,146 @@
# Шпаргалка по SQL
<div align="right"><a href="https://github.com/cheatsnake/backend-cheats#%D1%80%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F-%D0%B1%D0%B0%D0%B7%D0%B0-%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85">Вернуться на главную страницу ⬆️</a></div>
- Создание новой БД
```sql
CREATE DATABASE db_name;
```
- Создание новой таблицы
```sql
CREATE TABLE users (
id SERIAL PRIMARY KEY, # Уникальный id
firstName VARCHAR(100), # Строка
lastName VARCHAR(100), # Строка
age INT, # Число
gender VARCHAR(10), # Строка
isMarried BOOLEAN # true/false
);
```
- Основные типы данных
> - INT (целые числа от -2^32 до +2^32)
> - FLOAT / DOUBLE / DECIMAL (дробные числа)
> - CHAR / VARCHAR / TEXT (строки)
> - DATA / DATETIME / TIME (дата и время)
> - ENUM (перечисления - списки допустимых значений)
> - [И другие](https://sql-language.ru/osnova-sql/tipy-dannykh-sql.html)
- Добавление данных в таблицу
```sql
INSERT INTO users(
firstName, lastName, age, gender, isMarried
) VALUES (
'Alex', 'Manson' 25, 'male', false
);
```
- Выборка данных из таблицы
```sql
# SELECT
## Получить всю таблицу users
SELECT * FROM users;
## Получить только столбцы firstName и age из таблицы users
SELECT firstName, age FROM users;
# LIMIT
## Получить первых 20 записей таблицы users
SELECT * FROM users LIMIT 20;
# DISTINCT
## Получить только уникальные значения из столбца firstName
SELECT DISTINCT(firstName) FROM users;
# WHERE
## Записи, где столбец gender = 'male'
SELECT * FROM users WHERE gender = 'male';
## AND, OR
SELECT * FROM users WHERE age = 25 AND isMarried = falsel
SELECT * FROM users WHERE age = 20 OR age = 50;
# BETWEEN
## Записи, где значения столбца age находятся в промежутке от 20 до 30
SELECT * FROM users WHERE age BETWEEN 20 AND 30;
#NULL
## Записи, где столбец lastName не пуст
SELECT * FROM users WHERE lastName IS NOT NULL;
```
- Поиск данных по шаблону
```sql
# IN, LIKE, NOT LIKE
## % - подстановочный знак, который указывает на любое кол-во символов
## _ - подстановочный знак, который указывает на один символ
## Записи, где firsName равен 'John', 'Mike' или 'Kane'
SELECT * FROM users WHERE firstName IN ('John', 'Mike', 'Kane');
## Записи, где firsName начинается c буквы 'A'
SELECT * FROM users WHERE firstName LIKE 'A%';
## Записи, где первая буква в firstName равна 'A', 'B' или 'C'
SELECT * FROM users WHERE firstName LIKE '[ABC]%';
## Записи, где вторая буква в firsName не равна 'o'
SELECT * FROM users WHERE firstName NOT LIKE '_o%';
```
- Сортировка и фильтрация данных таблиц
```sql
# ORDER BY
## ASC - по возрастанию (по умолчанию)
## DESC - по убыванию
SELECT * FROM users ORDER BY firstName ASC;
SELECT * FROM users ORDER BY age DESC;
SELECT * FROM users ORDER BY lastName DESC, isMarried ASC;
# HAVING
## Фильтрация результатов группировки
```
- Использование псевдонимов
```sql
# AS
SELECT firstName AS name FROM users WHERE name = "Alex";
```
- Изменение таблиц
```sql
# ALTER TABLE
## Добавить новую колонку city к таблицe users
ALTER TABLE users ADD COLUMN city VARCHAR(50);
## Удалить колонку isMarried из таблицы users
ALTER TABLE users DROP COLUMN isMarried;
## Переименовать колонку firstName в fName в таблицe users
ALTER TABLE users RENAME COLUMN firstName TO fName;
## Переименовать таблицу users в consumers
ALTER TABLE users RENAME TO consumers;
```
- Изменение данных в таблице
```sql
# UPDATE
## Изменить в таблицe users записать с id = 1
UPDATE users SET firstName = 'Kale', age = 33 WHERE id = 1;
## Изменить записи, где gender = 'female'
UPDATE users SET city = 'Paris' WHERE gender = 'famale';
```
- Удаление данных из таблицы
```sql
# DELETE
# Удалить запись в таблице users, где id = 2
DELETE FROM users WHERE id = 2;
# Удалить все записи в таблице users, где gender = 'male'
DELETE FROM users WHERE gender = 'male';
```
- [Агрегатные функции](https://codetown.ru/sql/agregatnye-funkcii/)
> Используются для обобщения/подсчёта данных.
```sql
# COUNT
## Возвращает количество элементов в таблице users
SELECT COUNT(*) FROM users;
## Возвращает количество не повторяющихся значений столбца firstName
SELECT COUNT(DISTINCT(firstName)) FROM users;
# MAX, MIN
SELECT MAX(age) FROM users;
SELECT MIN(age) FROM users;
# SUM
# Сумма всех значений столбца age
SELECT SUM(age) FROM users;
# AVG
## Среднее значение столбца age
SELECT AVG(age) FROM users;
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

@ -0,0 +1,813 @@
# Шпаргалка по Bash скриптам
<div align="right"><a href="https://github.com/cheatsnake/backend-cheats#%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%8B-bash">Вернуться на главную страницу ⬆️</a></div>
**Содержание:**
- [Hello world](#hello-world)
- [Комментарии](#комментарии)
- [Переменные](#переменные)
- [Пользовательский ввод](#пользовательский-ввод)
- [Передача аргументов](#передача-аргументов)
- [Условия if else](#условия-if-else)
- [Операторы условий](#операторы-условий)
- [Логические операторы](#логические-операторы)
- [Арифметические операторы](#арифметические-операторы)
- [Конструкция switch case](#конструкция-switch-case)
- [Массивы](#массивы)
- [Цикл while](#цикл-while)
- [Цикл until](#цикл-until)
- [Цикл for](#цикл-for)
- [Цикл select](#цикл-select)
- [Break и continue в циклах](#break-и-continue-в-циклах)
- [Функции](#функции)
- [Локальные переменные](#локальные-переменные)
- [Ключевое слово readonly](#ключевое-слово-readonly)
- [Обработка сигналов](#обработка-сигналов)
Скрипты Bash имеют расширение `.sh`:
```
$ touch script.sh
```
Хорошей практикой считается указывать путь до вашего терминала вначале каждого скрипта:
```sh
#! /bin/bash
```
> Этот прием называется **shebang**, подробнее можно почитать [тут](https://ru.wikipedia.org/wiki/%D0%A8%D0%B5%D0%B1%D0%B0%D0%BD%D0%B3_(Unix))
Список доступных терминалов в вашей системе можно посмотреть с помощью этой команды:
```
$ cat /etc/shells
```
## Hello world
```sh
#! /bin/bash
echo "Hello world"
```
Запуск скрипта:
```
$ bash script.sh
```
Скрипт можно сделать исполняемым файлом и запускать без команды `bash`:
```
$ chmod +x script.sh
```
```
$ ./script.sh
```
## Комментарии
Однострочные комментарии:
```sh
# Это просто коммент
# И это тоже
echo "Hello from bash" # эта команда выводит строку в консоль
```
Мультистрочные комментарии:
```sh
: 'Мультистрочные комментарии очень удобны
для подробного описания ваших скриптов.
Успользуйте их с умом!'
```
## Переменные
```sh
MY_STRING="bash is cool"
echo $MY_STRING # Вывод значения переменной
```
> Имя переменной не должно начинаться с цифры
## Пользовательский ввод
Команда `read` читает пользовательский ввод и записывает его в указанную переменную:
```sh
echo "Введите ваше имя:"
read NAME
echo "Привет $NAME!"
```
> Если переменная не указана, то команда `read` по умолчанию сохранит все данные в переменную `REPLY`
Можно записывать несколько переменных. Для этого, при вводе из терминала, значения необходимо разделять пробелом:
```sh
read V1 V2 V3
echo "1 переменная: $V1"
echo "2 переменная: $V2"
echo "3 переменная: $V3"
```
```
$ bash script.sh
$ hello world some other text
1 переменная: hello
2 переменная: world
3 переменная: some other text
```
Флаг `-a` позволяет создать массив в который будут записываться строки пользовательского ввода разделенные пробелом:
```sh
read -a NAMES
echo "Массив имён: ${NAMES[0]}, ${NAMES[1]}, ${NAMES[2]}"
```
```
$ bash script.sh
Alex Mike John
Массив имён: Alex, Mike, John
```
Флаг `-p` позволяет не переносить пользовательский ввод на следующую строку.
Флаг `-s` позволяет скрыть вводимые символы (как это происходит при вводе пароля).
```sh
read -p "Введите ваш логин: " LOGIN
read -sp "Введите ваш пароль: " PASSWD
```
```
$ bash script.sh
Введите ваш логин: bash_hacker
Введите ваш пароль:
```
## Передача аргументов
Аргументы это просто значения, которые могут быть указаны при запуске скрипта.
Всем переданным аргументам присваивается уникальное имя равное их порядковому номеру:
```sh
echo "Аргумент 1 - $1; aргумент 1 - $2; aргумент 1 - $3."
```
```
$ bash script.sh hello test 1337
Аргумент 1 - hello; aргумент 1 - test; aргумент 1 - 1337.
```
Нулевой аргумент всегда равен названию файла со скриптом:
```sh
echo "Вы запустили файл $0"
```
```
$ bash script.sh
Вы запустили файл script.sh
```
Все аргументы можно положить в именованный массив:
```sh
args=("$@")
echo "Полученные аргументы: ${args[0]}, ${args[1]}, ${args[2]}."
```
```
$ bash script.sh some values 123
Полученные аргументы: some, values, 123
```
> `@` - это название массива по умолчанию, который хранит все аргументы (за исключением нулевого)
Количество переданных аргументов (за исключением нулевого) хранится в переменной `#`:
```sh
echo "Всего получено аргументов: $#"
```
## Условия if else
Условия всегда начинаются с ключевого слова `if` и заканчиваются на `fi`:
```sh
echo "Введите ваш возраст:"
read AGE
if (($AGE >= 18))
then
echo "Доступ разрешен"
else
echo "Доступ запрещен"
fi
```
```
$ bash script.sh
Введите ваш возраст:
19
Доступ разрешен
$ bash script.sh
Введите ваш возраст:
16
Доступ запрещен
```
Условий может быть сколько угодно много, для этого используется конструкция `elif`, которая также как `if` может проверять условия:
```sh
read COMMAND
if [ $COMMAND = "help" ]
then
echo "Доступные команды:"
echo "ping - вернет строку PONG"
echo "version - вернет номер версии программы"
elif [ $COMMAND = "ping" ]
then
echo "PONG"
elif [ $COMMAND = "version" ]
then
echo "v1.0.0"
else
echo "Команда не определена. Воспользуйтесь командой 'help' для справки"
fi
```
> Обратите внимание, что после конструкций `if` и `elif` всегда следует строчка с ключевым словом `then` <br>
> Так же не забывайте отделять условия пробелами внутри фигурных скобок -> `[ condition ]`
## Операторы условий
Для цифр и строк могут использоваться разные операторы сравнения. Полные их списки с примерами приведены в таблицах ниже.
> Обратите внимания, что разные операторы используются с определенными скобками
### Операторы сравнения для чисел
| Оператор | Описание | Пример |
| -------- | -------------------- | ------------------ |
| -eq | равняется ли | if [ $age -eq 18 ] |
| -ne | не равняется | if [ $age -ne 18 ] |
| -gt | больше чем | if [ $age -gt 18 ] |
| -ge | больше чем или равно | if [ $age -ge 18 ] |
| -lt | меньше чем | if [ $age -lt 18 ] |
| -le | меньше чем или равно | if [ $age -le 18 ] |
| > | больше чем | if (($age > 18)) |
| < | меньше чем | if (($age < 18)) |
| => | больше чем или равно | if (($age => 18)) |
| <= | меньше чем или равно | if (($age <= 18)) |
### Операторы сравнения для строк
| Оператор | Описание | Пример |
| -------- | ------------------------------------------- | ------------------------ |
| = | проверка на равенство | if [ $str = "hello" ] |
| == | проверка на равенство | if [ $str == "hello" ] |
| != | проверка на НЕ равенство | if [ $str != "hello" ] |
| < | сравнение меньше чем по ASCII коду символов | if [[ $str < "hello" ]] |
| > | сравнение больше чем по ASCII коду символов | if [[ $str > "hello" ]] |
| -z | проверка пустая ли строка | if [ -z $str ] |
| -n | проверка есть ли в строке хоть один символ | if [ -n $str ] |
Так же существуют операторы для проверки различных условий над файлами.
### Операторы для проверки файлов
| Оператор | Описание | Пример |
| -------- | --------------------------------------------------------------------------------- | --------------- |
| -e | проверяет, существует ли файл | if [ -e $file ] |
| -s | проверяет, пустой ли файл | if [ -s $file ] |
| -f | проверяет, является ли файл обычным файлом, а не каталогом или специальным файлом | if [ -f $file ] |
| -d | проверяет, является ли файл каталогом | if [ -d $file ] |
| -r | проверяет, доступен ли файл для чтения | if [ -r $file ] |
| -w | проверяет, доступен ли файл для записи | if [ -w $file ] |
| -x | проверяет, является ли файл исполяемым | if [ -x $file ] |
## Логические операторы
Условия с оператором "И" возвращают истину только в том случае, когда все условия истины.
> Существует несколько вариантов написания условий с логическими операторами
```sh
if [ $age -ge 18 ] && [ $age -le ]
```
```sh
if [ $age -ge 18 -a $age -le ]
```
```sh
if [[ $age -ge 18 && $age -le ]]
```
Условия с оператором "ИЛИ" возвращают истину в том случае, когда хотя бы одно условие истинно.
```sh
if [ -r $file ] || [ -w $file ]
```
```sh
if [ -r $file -o -w $file ]
```
```sh
if [[ -r $file || -w $file ]]
```
## Арифметические операторы
```bash
num1=10
num2=5
# Сложение
echo $((num1 + num2)) # 15
echo $(expr $num1 + $num2) # 15
# Вычитание
echo $((num1 - num2)) # 5
echo $(expr $num1 - $num2) # 5
# Умножение
echo $((num1 * num2)) # 50
echo $(expr $num1 \* $num2) # 50
# Деление
echo $((num1 / num2)) # 2
echo $(expr $num1 / $num2) # 2
# Остаток от деления
echo $((num1 % num2)) # 0
echo $(expr $num1 % $num2) # 0
```
> Обратите внимание, что при использовании умножения с ключевым словом `expr` необходимо использовать косую черту.
## Конструкция switch case
Не всегда удобно использовать конструкции if/elif для большого количества условий. Для этого лучше подойдет конструкция case:
```sh
read COMMAND
case $COMMAND in
"/help" )
echo "Вы открыли справочное меню" ;;
"/ping" )
echo "PONG" ;;
"/version" )
echo "Текущая версия: 1.0.0" ;;
* )
echo "Такой команды нет :(" ;;
esac
```
> Случай со звездочкой * отработает лишь в том случае, если не подойдет ни одно из условий выше.
## Массивы
Массивы позволяют хранить целую коллекцию данных в одной переменной. С этой переменной можно удобно и легко взаимодействовать:
```sh
array=('aaa' 'bbb' 'ccc' 'ddd')
echo "Элементы массива: ${array[@]}"
echo "Первый элемент массива: ${array[0]}"
echo "Индексы элементов массива: ${!array[@]}"
array_length=${#array[@]}
echo "Длинна массива: ${array_length}"
echo "Последний элемент массива: ${array[$((array_length - 1))]}"
```
```
$ bash script.sh
Элементы массива: aaa bbb ccc ddd
Первый элемент массива: aaa
Индексы элементов массива: 0 1 2 3
Длинна массива: 4
Последний элемент массива: ddd
```
> Обратите внимание, что элементы массива разделются пробелом без запятой.
Элементы массива можно добавлять/перезаписывать/удалять по ходу выполнения скрипта:
```sh
array=('a' 'b' 'c')
array[3]='d'
echo ${array[@]} # a b c d
array[0]='x'
echo ${array[@]} # x b c d
array[0]='x'
echo ${array[@]} # x b c d
unset array[2]
echo ${array[@]} # x b d
```
## Цикл while
Цикл while повторяет выполение блока кода описанного между ключевыми словами `do` - `done` пока истино заданное условие.
```sh
i=0
while (( $i < 5 ))
do
i=$((i + 1))
echo "Итерация номер $i"
done
```
```
$ bash script.sh
Итерация номер 1
Итерация номер 2
Итерация номер 3
Итерация номер 4
Итерация номер 5
```
Операция увеличения числа на 1 единицу называется инкриментом и для неё существует специальная запись:
```sh
(( i++ )) # post increment
```
```sh
(( ++i )) # pre increment
```
Противоположная операция - декремент:
```sh
(( i-- )) # post decrement
```
```sh
(( --i )) # pre decrement
```
С помощью while циклов можно построчно читать различные файлы. Существует несколько способов сделать это:
```sh
echo "Чтение файла по строкам:"
while read line
do
echo $line
done < text.txt
```
```sh
echo "Чтение файла по строкам:"
cat text.txt | while read line
do
echo $line
done
```
```sh
echo "Чтение файла по строкам:"
while IFS='' read -r line
do
echo $line
done < text.txt
```
## Цикл until
Цикл until противоположен циклу while тем, что он выполняет блок кода описанный между ключевыми словами `do` - `done` тогда, когда заданное условие возвращает false:
```sh
i=5
until (( $i == 0 )) # будет выполняться пока i не станет равным 0
do
echo "Значение переменной i = $i"
(( i-- ))
done
```
```
$ bash script.sh
Значение переменной i = 5
Значение переменной i = 4
Значение переменной i = 3
Значение переменной i = 2
Значение переменной i = 1
```
## Цикл for
Самый классический цикл:
```sh
for (( i=1; i<=10; i++ ))
do
echo $i
done
```
В новых версиях Bash существует более удобный способ записи с помощью оператора `in`:
```sh
for i in {1..10}
do
echo $i
done
```
Условие после ключевого слова `in` в общем случае выгядит так:
```
{START..END..INCREMENT}
```
> _START_ - с какого элемента начинать цикл; <br>
> _END_ - до какого элемента продолжать цикл; <br>
> _INCREMENT_ - на сколько увеличивать элемент после каждой итерации (по умолчанию на 1).
Цикл for можно использовать для последовательного запуска набора команд:
```sh
for command in ls pwd date # Список команд для запуска
do
echo "---Запуск команды $command---"
$command
echo "------------------------"
done
```
```
$ bash script.sh
---Запуск команды ls---
script.sh text.txt
------------------------
---Запуск команды pwd---
/home/user/bash
------------------------
---Запуск команды date---
Сб 03 сен 2022 10:35:57 +03
------------------------
```
Ключевое слово `break` останавливает выполнение цикла.
Ключевое слово `continue` завершает текущую итерацию цикла и переходит к следующей. <br>
## Цикл select
Крайне удобный цикл для создания меню выбора опций:
```sh
select color in "Красный" "Зеленый" "Синий" "Белый"
do
echo "Вы выбрали $color цвет..."
done
```
```
$ bash script.sh
1) Красный
2) Зеленый
3) Синий
4) Белый
#? 1
Вы выбрали Красный цвет...
#? 2
Вы выбрали Зеленый цвет...
#? 3
Вы выбрали Синий цвет...
#? 4
Вы выбрали Белый цвет...
```
Цикл `select` очень хорошо сочетается с оператором выбора `case`. Таким образом можно очень просто создавать интерактивные консольные приложения с большим количеством разветвлений:
```sh
echo "---Добро пожаловать в меню---"
select cmd in "Запуск" "Настройки" "О программе" "Выход"
do
case $cmd in
"Запуск")
echo "Программа запущена"
echo "Введите число:"
read input
echo "$input в квадрате = $(( input * input ))" ;;
"Настройки")
echo "Настройки программы" ;;
"О программе")
echo "Версия 1.0.0" ;;
"Выход")
echo "Выход из программы..."
break ;;
esac
done
```
## Break и continue в циклах
Для принудительного выхода из цикла используется ключевое слово `break`:
```sh
count=1
while (($count)) # всегда возвращает истину
do
if (($count > 10))
then
break # принудительный выход несмотря на условие после while
else
echo $count
((count++))
fi
done
```
Для того, чтобы пропустить выполнение текущей итерации в цикле и перейти к следующей - используется ключевое слово `continue`:
```sh
for (( i=5; i>0; i-- ))
do
if ((i % 2 == 0))
then
continue
fi
echo $i
done
```
```
$ bash script.sh
5
3
1
```
## Функции
Функции - это именованные участки кода, которые могут переиспользоваться неограниченное количество раз:
```sh
hello() {
echo "Hello World!"
}
# вызываем функцию 3 раза:
hello
hello
hello
```
```
$ bash script.sh
Hello World!
Hello World!
Hello World!
```
Функции, так же, как и сами скрипты, могут принимать аргументы. Они имеют такие же названия, но аргументы функций видны только внутри функции, в которую они были переданы:
```sh
echo "$1" # аргумент переданный при запуске скрипта
calc () {
echo "$1 + $2 = $(($1 + $2))"
}
# передача двух аргументов в функцию calc
calc 42 17
```
```
$ bash script.sh hello
hello
42 + 17 = 59
```
## Локальные переменные
Если мы объявим какую-либо переменную, а затем объявим ещё одну с таким же именем, но уже внутри функции, то у нас произойдет перезапись:
```sh
VALUE="hello"
test() {
VALUE="linux"
}
test
echo $VALUE
```
```
$ bash script.sh
linux
```
Чтобы предотвратить такое поведение используются ключевое слово `local` перед именем переменной, которая объявляется внутри функции:
```sh
VALUE="hello"
test() {
local VALUE="linux"
echo "Переменная внутри функции: $VALUE"
}
test
echo "Глобальная переменная: $VALUE"
```
```
$ bash script.sh
Переменная внутри функции: linux
Глобальная переменная: hello
```
## Ключевое слово readonly
По умолчанию, каждая созданная переменная в Bash в последующем может перезаписываться. Чтобы защитить переменную от изменений можно использовать ключевое слово `readonly`:
```sh
readonly PI=3.14
PI=100
echo "PI = $PI"
```
```
$ bash script.sh
script.sh: строка 2: PI: переменная только для чтения
PI = 3.14
```
`readonly` можно использовать не только в момент объявления переменной, но и после:
```sh
VALUE=123
VALUE=$(($VALUE * 1000))
readonly VALUE
VALUE=555
echo $VALUE
```
```
$ bash script.sh
script.sh: строка 4: VALUE: переменная только для чтения
123000
```
Тоже самое касается функций. Они так же могут быть переопределены, поэтому их можно защитить с помощью `readonly` указав при этом флаг `-f`:
```sh
test() {
echo "This is test function"
}
readonly -f test
test() {
echo "Hello World!"
}
test
```
```
$ bash script.sh
script.sh: строка 9: test: значение функции можно только считать
This is test function
```
## Обработка сигналов
Во время выполнения скриптов, могут происходить неожиданные действия. Например, пользователь может прервать выполнения скрипта с помощь комбинации `Ctrl + C`, либо может случайно закрыть терминал или в самом скрипте может случится какая-либо ошибка и так далее...
В POSIX-системах существуют специальные сигналы - уведомления процесса о каком-либо событии. Их список определен в таблице ниже:
| Сигнал | Код | Действие | Описание |
| ------- | -------- | -------------------------- | -------------------------------------------------------- |
| SIGHUP | 1 | Завершение | Закрытие терминала |
| SIGINT | 2 | Завершение | Сигнал прерывания (Ctrl-C) с терминала |
| SIGQUIT | 3 | Завершение с дампом памяти | Сигнал «Quit» с терминала (Ctrl-) |
| SIGILL | 4 | Завершение с дампом памяти | Недопустимая инструкция процессора |
| SIGABRT | 6 | Завершение с дампом памяти | Сигнал, посылаемый функцией abort() |
| SIGFPE | 8 | Завершение с дампом памяти | Ошибочная арифметическая операция |
| SIGKILL | 9 | Завершение | Процесс уничтожен (kill signal) |
| SIGSEGV | 11 | Завершение с дампом памяти | Нарушение при обращении в память |
| SIGPIPE | 13 | Завершение | Запись в разорванное соединение (пайп, сокет) |
| SIGALRM | 14 | Завершение | Сигнал истечения времени, заданного alarm() |
| SIGTERM | 15 | Завершение | Сигнал завершения (сигнал по умолчанию для утилиты kill) |
| SIGUSR1 | 30/10/16 | Завершение | Пользовательский сигнал № 1 |
| SIGUSR2 | 31/12/17 | Завершение | Пользовательский сигнал № 2 |
| SIGCHLD | 20/17/18 | Игнорируется | Дочерний процесс завершен или остановлен |
| SIGCONT | 19/18/25 | Продолжить выполнение | Продолжить выполнение ранее остановленного процесса |
| SIGSTOP | 17/19/23 | Остановка процесса | Остановка выполнения процесса |
| SIGTSTP | 18/20/24 | Остановка процесса | Сигнал остановки с терминала (Ctrl-Z) |
| SIGTTIN | 21/21/26 | Остановка процесса | Попытка чтения с терминала фоновым процессом |
| SIGTTOU | 22/22/27 | Остановка процесса | Попытка записи на терминал фоновым процессом |
В Bash есть ключевое слово `trap` с помощью которого можно отлавливать различные сигналы и предусматривать выполнение определенных команд:
```
trap <КОМАНДА> <СИГНАЛ>
```
> Под сигналом можно использовать его название (колонка _Сигнал_ в таблице), либо его код (колонка _Код_ в таблице). Можно указывать несколько сигналов разделяя их названия или коды пробелом. <br>
> **Исключения:** сигналы SIGKILL (9) и SIGSTOP (17/19/23) отловить невозможно, поэтому нет смысла их указывать.
```sh
trap "echo Выполнение программы прервано...; exit" SIGINT
for i in {1..10}
do
sleep 1
echo $i
done
```
```
$ bash script.sh
1
2
3
4
^CВыполнение программы прервано...
```
## Отладка скриптов
Запуск скрипта с параметром `-x` покажет его поэтапное выполнение, что будет полезно при отладке и поиске ошибок:
```
$ bash -x script.sh
```
<div align="right"><a href="https://github.com/cheatsnake/backend-cheats/blob/master/files/linux/bash-scripts-cheatsheet.md#%D1%88%D0%BF%D0%B0%D1%80%D0%B3%D0%B0%D0%BB%D0%BA%D0%B0-%D0%BF%D0%BE-bash-%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B0%D0%BC">Вернуться в начало ⬆️</a></div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save