Professional Documents
Culture Documents
INterview
INterview
ІНКАПСУЛЯЦІЯ
Одним з визначальних факторів при проектуванні компонентів програми є
приховування внутрішніх даних компоненту і деталей його реалізації від інших
компонентів програми та надання набору методів для взаємодії з ним (API). Цей
принцип є одним з чотирьох фундаментальних принципів ООП і називається
інкапсуляцією.
НАСЛІДУВАННЯ
Наслідування є одним з найвагоміших принципів об'єктно-орієнтованого
програмування, оскільки воно дозволяє створювати ієрархічні структури об'єктів.
Використовуючи наслідування можна створити загальний клас, який буде
визначати характеристики і поведінку, властиві певному набору пов'язаних
об'єктів. В подальшому цей клас може наслідуватися іншими, другорядними
класами, кожен з яких додаватиме унікальні, властиві лише йому характеристики і
доповнюватиме або змінюватиме поведінку базового класу.
ПОЛІМОРФІЗМ
Розглядаючи поліморфізм необхідно пам'ятати, що цей принцип нерозривно
пов'язаний з іншим принципом ООП – наслідуванням, яке допомагає реалізувати
поліморфізм. Візьмемо для прикладу абстрактний клас «Автомобіль», який
наслідують два конкретних класи – «Спортивний автомобіль» та «Вантажний
автомобіль».
1. Один файл: При першому завантаженні сторінки, сервер передає весь код додатку
разом із сторінкою, зазвичай у вигляді одного файлу HTML, CSS та JavaScript. Це
дозволяє знизити затримки завантаження і покращити швидкість відкриття додатку.
2. Асинхронні запити: Додаток взаємодіє з сервером через асинхронні запити,
зазвичай з використанням технологій AJAX або Fetch API, щоб отримувати або
відправляти дані без перезавантаження сторінки.
3. Зміна контенту без перезавантаження: Завдяки JavaScript та DOM-маніпуляціям,
додаток може динамічно змінювати контент на сторінці без необхідності повного
перезавантаження сторінки.
4. Використання SPA-фреймворків: Для розробки SPA-додатків використовуються
різноманітні фреймворки та бібліотеки, такі як Angular, React, Vue.js, і т.д. Вони
надають потужні інструменти для розробки складних SPA з багатою
функціональністю.
Переваги SPA:
GET і POST - це два з основних HTTP методів, які використовуються для взаємодії з
веб-серверами. Вони виконують різні функції і мають деякі відмінності:
1. Значення даних:
GET: Дані запиту передаються у URL-параметрах. Ці дані видимі в адресному
рядку браузера і обмежені довжиною URL. Тому GET-запити
використовуються для запитів на отримання інформації з сервера.
POST: Дані запиту передаються у тілі запиту. Ці дані приховані від
користувача і не обмежені довжиною URL. POST-запити використовуються
для відправки даних на сервер для обробки, створення, оновлення або
видалення ресурсів.
2. Кешування:
GET: Результати GET-запитів зазвичай кешуються, тобто браузер може
зберігати результати запиту, щоб зменшити навантаження на сервер і
покращити швидкість відображення сторінок.
POST: POST-запити не кешуються, оскільки вони можуть змінювати стан
сервера або виконувати інші небезпечні дії.
3. Взаємодія з базами даних:
GET: GET-запити не повинні змінювати стан сервера або бази даних. Вони
призначені для отримання даних з сервера без побічних ефектів.
POST: POST-запити можуть змінювати стан сервера або бази даних, тому їх
використовують для збереження, оновлення або видалення даних на
сервері.
4. Безпека:
GET: GET-запити менш безпечні з точки зору безпеки, оскільки дані
передаються у URL і можуть бути видимі в логах сервера та історії браузера.
POST: POST-запити більш безпечні, оскільки дані передаються у тілі запиту і
не видимі в адресному рядку.
Плюси Docker:
Мінуси Docker:
1. Додатковий шар: Використання Docker додає додатковий шар абстракції та
управління контейнерами, що може призводити до невеликого падіння
продуктивності.
2. Ресурсомісткість: Docker потребує додаткових ресурсів, таких як пам'ять і
обчислювальну потужність, для управління контейнерами.
3. Складність мережі: Контейнеризація може створювати додаткові виклики з
управління мережами, особливо для додатків, що вимагають зв'язку між
контейнерами.
1. Unit-тести:
Призначення: Unit-тести перевіряють окремі частини програми (функції,
методи, класи) - так звані "одиниці коду". Вони виконуються для
переконання в правильності роботи конкретного шматка коду і виправлення
помилок, якщо такі виявляються.
Ізоляція: Unit-тести зазвичай запускаються ізольовано від інших частин
програми. Це досягається за допомогою моків (mocks) або підроблених
об'єктів (stubs), що замінюють залежності модуля.
Швидкість: Unit-тести є дуже швидкими, оскільки вони тестують окремі
частини коду і не включають в себе всю інфраструктуру або інші внутрішні
компоненти.
2. Інтеграційні тести:
Призначення: Інтеграційні тести перевіряють взаємодію між компонентами
або модулями програми. Вони виконуються для переконання, що різні
частини програми правильно співпрацюють одна з одною.
Реальні залежності: Інтеграційні тести включають реальні залежності між
компонентами програми, тому вони тестують реальний потік даних та
взаємодію з базами даних, зовнішніми службами тощо.
Повільність: Інтеграційні тести можуть бути повільнішими в порівнянні з unit-
тестами, оскільки вони включають в себе більше компонентів і залежностей.
В .NET, для написання unit-тестів часто використовуються фреймворки, такі як
MSTest, NUnit або xUnit.NET. Ці фреймворки допомагають створювати і запускати
тести з ізольованими залежностями. Для написання інтеграційних тестів, можна
використовувати той же фреймворк, але тестувати взаємодію між компонентами в
реальних умовах.
1. call: Ключове слово call використовується для здійснення виклику функції або
методу в програмі. Після виконання виклику адреса повернення і поточний стан
виконання поміщаються у стек.
2. ret: Ключове слово ret (або return) використовується для повернення з функції
або методу до місця, звідки відбувся виклик. Це відбувається після завершення
виконання функції.
3. push: Ключове слово push використовується для додавання значення у стек. Це
може використовуватись, наприклад, для передачі аргументів у функції або для
збереження даних перед викликом іншої функції.
4. pop: Ключове слово pop використовується для видалення значення з вершини
стеку. Це використовується для видалення адреси повернення або інших даних
після повернення з функції.
В ASP.NET MVC або ASP.NET Core є кілька типів Action фільтрів (Action filters), які
дозволяють впливати на обробку HTTP-запитів та HTTP-відповідей контролерами.
Action фільтри дають можливість виконувати дії перед та після виконання дій
контролерів або змінювати результат виконання дій.
Web Service (веб-сервіс) - це програмний компонент, який надає функції та дані для
зовнішніх клієнтів через мережу Інтернет. Веб-сервіси дозволяють різним
програмам, розташованим на різних платформах, взаємодіяти і обмінюватися
даними за допомогою стандартних веб-протоколів, таких як HTTP і XML.
1. Пошук кореневих об'єктів: Під час процесу зборки сміття збирач спочатку
знаходить всі кореневі об'єкти, які відомі системі або відомі безпосередньо з
поточного контексту виконання (наприклад, глобальні змінні, об'єкти на стеку).
2. Маркування: Після знаходження кореневих об'єктів збирач розпочинає процес
маркування. Він помічає всі об'єкти, до яких можна дістатися з кореневих об'єктів.
Всі марковані об'єкти вважаються активними і зберігаються в пам'яті.
3. Сканування: Збирач сміття сканує пам'ять, перевіряючи кожен об'єкт і відмічаючи
ті, до яких можна дістатися, через активні посилання. Об'єкти, які не були
марковані, вважаються сміттям і готуються до видалення.
4. Очищення: На цьому етапі збирач сміття вивільняє пам'ять, зайняту сміттям,
шляхом їх видалення. Це робиться шляхом розподілу пам'яті, яка раніше була
зайнята сміттям, і призначення її для майбутнього використання.
В .NET делегат - це тип даних, який представляє посилання на метод. Він дозволяє
передавати метод як аргумент і викликати його пізніше через це посилання. Це
дозволяє створювати гнучкі і потужні механізми для зв'язку об'єктів та реалізації
зворотнього виклику.
У .NET існує кілька вбудованих делегатів, таких як Action, Func, Predicate, які
забезпечують підтримку типових сигнатур методів, щоб не створювати власних
делегатів кожного разу, коли потрібно передати метод. Наприклад:
Так, Delegate і Action в .NET - це різні речі, але обидва вони використовуються для
роботи з делегатами.
Delegate - це базовий клас для всіх делегатів в .NET. Він представляє собою
загальний тип делегата і може представляти методи з будь-якими типами
параметрів і поверненням значень. Це означає, що ви можете створювати свої
власні делегати, які можуть використовуватись для представлення різних типів
методів залежно від потреб вашої програми. Однак використання базового класу
Delegate є не таким зручним, оскільки потребує явного вказання типів параметрів і
повернення методу.
Action - це один із вбудованих делегатів в .NET, який вже має фіксований тип
параметрів і не повертає значення (повертається void). Це спрощує використання,
оскільки вам не потрібно явно вказувати типи параметрів. Він визначений в .NET як
генерік делегата і може приймати від 0 до 16 параметрів. Також існують версії
Action для випадків, коли потрібно повертати значення - Func, але це вже інший
тип делегата.
В .NET є кілька основних типів даних, які можуть бути використані для зберігання
різних видів інформації. Ось деякі з них:
1. Числові типи:
int: 32-бітне ціле число.
long: 64-бітне ціле число.
float: 32-бітне число з плаваючою точкою.
double: 64-бітне число з плаваючою точкою.
decimal: 128-бітне число з плаваючою точкою з великою точністю.
2. Типи символів і рядків:
char: 16-бітний символ Unicode.
string: послідовність символів Unicode.
3. Типи булеві:
bool: логічний тип, який може мати значення true або false.
4. Тип дати і часу:
DateTime: тип для представлення дати та часу.
5. Масиви:
T[]: одновимірний масив з елементами типу T.
[,]: двовимірний масив.
[][]: масив масивів (рваний масив).
6. Колекції:
List<T>: список, який може містити елементи типу T.
Dictionary<TKey, TValue>: словник, який зберігає пари ключ-значення.
HashSet<T>: множина, яка містить унікальні елементи типу T .
7. Nullable типи:
int?: ціле число з можливістю бути null.
8. Перечислення (enum):
enum: набір іменованих цілочисельних констант.
9. Динамічний тип:
dynamic: тип, який дозволяє визначати тип даних під час виконання
програми
В .NET примітивні типи даних, відомі також як вбудовані типи даних, представляють
основні типи, які не є об'єктами, а виступають як основні одиниці даних і займають
фіксовані розміри в пам'яті. Ось деякі з примітивних типів даних в .NET:
1. Цілі числа:
int: 32-бітне ціле число, з діапазоном приблизно від -2,147,483,648 до
2,147,483,647.
long: 64-бітне ціле число, з діапазоном приблизно від -
9,223,372,036,854,775,808 до 9,223,372,036,854,775,807.
short: 16-бітне ціле число, з діапазоном приблизно від -32,768 до 32,767.
byte: 8-бітне ціле число, з діапазоном від 0 до 255.
sbyte: 8-бітне ціле число, з діапазоном приблизно від -128 до 127.
2. Числа з плаваючою точкою:
float: 32-бітне число з плаваючою точкою (одинарної точності).
double: 64-бітне число з плаваючою точкою (подвійної точності).
3. Символи:
char: 16-бітний символ Unicode.
4. Логічний тип:
bool: логічний тип, який може мати значення true або false.
Nullable-тип в .NET це тип даних, який дозволяє зберігати значення типу, а також
додатковою можливістю мати значення null. В інших словах, Nullable-тип дозволяє
представляти об'єкт, який може мати значення, подібне до примітивних типів, або
бути "пустим", тобто null.
Nullable-типи особливо корисні, коли ви маєте справу з базами даних або даними
зовнішніх джерел, де деякі значення можуть бути відсутніми. Вони дозволяють чітко
виражати, що деякі змінні можуть бути некоректними, і роблять код більш безпечним і
зрозумілим.
1. Тип значення:
Тип значення представляє одне значення і зберігає його напряму в області
пам'яті, відомої як стек (stack).
Змінні типу значення містять фактичне значення, а не посилання на нього.
Коли змінна типу значення копіюється або передається в якості параметра,
копіюється саме значення.
Коли ви оголошуєте змінну типу значення, вона зазвичай має значення за
замовчуванням.
Приклади типів значення: int, float, char, bool, struct, тощо.
2. Тип посилання:
Тип посилання представляє посилання на об'єкт або інший тип.
Змінні типу посилання містять адресу пам'яті, де зберігається фактичний
об'єкт або значення.
Коли змінна типу посилання копіюється або передається в якості параметра,
копіюється лише адреса, а не сам об'єкт.
Оскільки об'єкти знаходяться на кучі (heap), вони можуть існувати довше, ніж
змінні типу значення, які існують лише в межах своїх областей.
Приклади типів посилання: class, interface, delegate, object, тощо.
Структури (struct) є типами значення, вони можуть містити як прості значення, так і
інші структури. Структури часто використовуються для представлення невеликих
об'єктів з декількома властивостями і мають менший наклад на пам'ять, оскільки
зберігаються на стеці.
Класи (class) є типами посилання, і вони можуть мати більший розмір, оскільки
зберігаються на кучі (heap). Класи дозволяють створювати складні структури з
методами, властивостями та іншими типами даних.
В .NET основна відмінність між value і reference type полягає у тому, як вони
зберігаються та взаємодіють з пам'яттю:
Приклади value type: int, float, char, bool, struct (структури), enum тощо.
Приклади reference type: class (класи), interface, delegate, string (рядки), object тощо.
Отже, щодо вашого питання, String в .NET є представником reference type. Рядки
(String) у .NET зберігаються на купі (heap) та є неімутабельними, що означає, що їх
значення не можна змінювати після створення. Коли ви створюєте новий рядок
або змінюєте існуючий, насправді створюється новий об'єкт рядка, а не змінюється
оригінальний. Оскільки рядки можуть бути досить великими та займати багато
пам'яті, зберігання їх на стеці було б неефективним, тому вони зберігаються на купі
за допомогою reference type.
30.В чому відмінність між string builder і string?
1. Неякарність (Mutability):
string: Рядки в C# є незмінними (immutable), що означає, що після створення
рядка ви не можете його змінити. Кожне змінення рядка фактично приводить до
створення нового об'єкта рядка. Це може бути неефективним при обробці багато
рядків, оскільки прийдеться створювати багато проміжних об'єктів.
StringBuilder: Це мутабельна структура даних для роботи з рядками. Вона
дозволяє маніпулювати рядком, додаючи, видаляючи або змінюючи його, без
створення нових об'єктів рядка. Використання StringBuilder може бути значно
ефективнішим для складних операцій над рядками, особливо коли необхідно
виконувати багато змінень.
2. Використання:
string: Використовується для представлення незмінних рядків даних. Це найбільш
поширений тип для представлення текстових даних в C#.
StringBuilder: Використовується тоді, коли маємо потребу будувати рядок шляхом
додавання частин до нього. Це корисно, наприклад, при зчитуванні багато рядків з
файлу, побудові складних SQL-запитів, форматуванні виводу тощо.
3. Взаємодія з іншими класами:
string: Рядок (string) може взаємодіяти з багатьма іншими класами і бібліотеками, і
найчастіше використовується для представлення даних у форматі, який є
зрозумілим для більшості методів і функцій.
StringBuilder: StringBuilder дозволяє виконувати побудову рядків
безпосередньо, проте, якщо потрібно передати результат до методу, який очікує
рядок (string), ви можете сконвертувати StringBuilder до string, використовуючи
його метод ToString().
Boxing: Це процес, коли значковий тип даних (наприклад, int, double, bool тощо)
перетворюється в посилальний тип (object або інтерфейсний тип).
Array (Масив): Масив - це фіксований контейнер, який містить елементи одного типу даних.
Розмір масиву задається під час створення і не може бути змінений після цього.
List (Список): Список - це динамічний контейнер, який також містить елементи одного типу
даних. Розмір списку може змінюватись динамічно, коли додаються або видаляються
елементи.
Абстрактний клас:
Абстрактний клас є типом даних, який може містити абстрактні методи, але не
обов'язково повний набір реалізацій.
Ви не можете створювати об'єкти абстрактних класів безпосередньо. Вони
створюються тільки для успадковування.
Абстрактний клас може містити абстрактні методи, які не мають реалізації в самому
класі, але обов'язково повинні бути перевизначені в похідних класах.
Абстрактні класи використовуються для створення базової функціональності та
набору методів, які повинні бути реалізовані в похідних класах.
Клас, який успадковує абстрактний клас, повинен реалізувати всі абстрактні методи
цього класу.
38.Чим відрізняється абстрактний клас від інтерфейсу? Для чого потрібні інтерфейси і які
завдання вони виконують?
Абстрактний клас:
Абстрактний клас може містити як абстрактні методи (методи без реалізації), так і
звичайні методи з реалізацією.
Клас може успадковувати від одного абстрактного класу.
Абстрактний клас може містити поля, властивості, методи, конструктори, події та
інші елементи.
Абстрактні класи можуть мати імплементовані методи, що зменшує повторювану
реалізацію у похідних класах.
Інтерфейс:
1. override:
Ключове слово override вказує, що метод у похідному класі перевизначає
метод базового класу.
Метод, позначений як override, повинен мати таку ж саму сигнатуру, як і
метод у базовому класі.
Під час виклику методу з екземпляра похідного класу буде використована
реалізація методу з цього похідного класу, навіть якщо метод викликається
через посилання на базовий клас.
2.
3. new:
Ключове слово new вказує, що метод у похідному класі повністю
перевизначає метод базового класу, але це не пов'язано з поліморфізмом, як
у випадку override.
Метод, позначений як new, також повинен мати таку ж саму сигнатуру, як і
метод у базовому класі.
Відмінність в тому, що при виклику методу з екземпляра похідного класу
через посилання на базовий клас буде використана реалізація методу з
базового класу, незважаючи на наявність методу з ключовим словом new у
похідному класі.
Так, в платформі .NET екземпляр структури може бути збережений у купі (heap), але
це відбувається через упакування (boxing) і створення посилання на об'єкт.
1. Асинхронність:
Використовується для покращення відгуку програми та уникнення
блокування потоку.
Зазвичай використовується для довготривалих операцій, таких як мережеві
виклики, операції вводу-виводу та інші, які можуть забрати час.
Асинхронність може бути досягнута за допомогою async/await.
2. Багатопотоковість (Multithreading):
Використовується для одночасного виконання багатьох операцій на різних
потоках.
Зазвичай використовується для паралельного виконання завдань з метою
використання доступних ресурсів (наприклад, багатоядерних процесорів).
В .NET багатопотоковість може бути реалізована за допомогою класів Thread
та Task.
Взагалі кажучи, зупиняти деякі критичні винятки у блоках catch може призвести до
некоректної роботи програми або навіть до її падіння. Рекомендується
забезпечувати належне управління ресурсами, використовувати механізми
логування та виправлення помилок для обробки винятків у програмі.
72.Яка різниця між .NET Standard Class Library і .NET Core Class Library?
Вибір між AddTransient і AddScoped залежить від потреб вашого додатка та того, як
тривало потрібно, щоб об'єкти служб зберігали стан. Якщо ви працюєте з даними,
які мають бути унікальними для кожного HTTP-запиту, то AddScoped може бути
більш відповідним варіантом. Якщо ж вам потрібно створити новий об'єкт кожного
разу, коли його викликають, то AddTransient буде більш відповідним варіантом.
У моєму розумінні, чиста функція - це функція в програмуванні, яка має дві основні
властивості:
Типи зв'язності:
Типи зв'язаності:
Залежно від потреб та вимог проекту, вибір між IaaS, PaaS та SaaS може визначити, наскільки
велику відповідальність ви хочете взяти на себе щодо управління ресурсами та додатками.