Skip to content

Commit b85d448

Browse files
committed
docs(md): update and improve Python interview answers
1 parent a777127 commit b85d448

1 file changed

Lines changed: 65 additions & 16 deletions

File tree

README.md

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
- **Кросплатформеність**: один код працює на Linux, macOS, Windows.
1717
- **Мультипарадигменність**: procedural, OOP, functional підходи в одному проєкті.
1818
- **Сильна екосистема**: `pip`, `venv`, `pyproject.toml`, тисячі готових бібліотек.
19-
- **Сучасні можливості Python 3.14+**: type hints, `dataclass`, `async/await`, `match/case`, генератори, context managers.
19+
- **Сучасні можливості Python 3.10+**: type hints, `dataclass`, `async/await`, `match/case`, генератори, context managers.
2020

2121
Приклад production-style функції:
2222

@@ -36,7 +36,7 @@ def process_users(users: list[User]) -> list[str]:
3636

3737
- Python прискорює розробку завдяки простому синтаксису та великій стандартній бібліотеці.
3838
- Мова підходить для backend, automation, data/ML, тестування та DevOps.
39-
- У Python 3.14+ ключові практики: type hints, async IO, сучасний standard library.
39+
- У Python 3.10+ ключові практики: type hints, async IO, сучасний standard library.
4040

4141
</details>
4242

@@ -1681,13 +1681,20 @@ a == b # True
16811681
a is b # False
16821682
```
16831683

1684+
**Важливо про оптимізації (Interning):**
1685+
CPython кешує ("інтернує") малі цілі числа (від -5 до 256) та короткі рядки
1686+
на етапі компіляції/завантаження. Тому для них `is` може повертати `True`,
1687+
навіть якщо вони створені окремо. Але це деталі реалізації, на які не варто
1688+
покладатися в бізнес-логіці.
1689+
16841690
Для `None` завжди використовуйте `is`.
16851691

16861692
**Коротко:**
16871693

16881694
- `==` про рівність значень.
1689-
- `is` про той самий об'єкт.
1690-
- `value is None` це правильний стиль перевірки.
1695+
- `is` про той самий об'єкт у пам'яті.
1696+
- Interning може давати неочевидний `is True` для малих `int` та `str`.
1697+
- `value is None` — це єдиний правильний стиль для перевірки на `None`.
16911698

16921699
</details>
16931700

@@ -2064,7 +2071,10 @@ Python використовує правило LEGB для пошуку імен
20642071
найближчого enclosing-scope (не глобального).
20652072

20662073
```python
2067-
def counter() -> callable:
2074+
from collections.abc import Callable
2075+
2076+
2077+
def counter() -> Callable:
20682078
value = 0
20692079

20702080
def inc() -> int:
@@ -2876,7 +2886,7 @@ class User:
28762886
self.name = name
28772887

28782888
@classmethod
2879-
def from_email(cls, email: str) -> "User":
2889+
def from_email(cls, email: str) -> User:
28802890
return cls(email.split("@")[0])
28812891
```
28822892

@@ -2971,11 +2981,21 @@ class Point:
29712981
self.y = y
29722982
```
29732983

2984+
**Нюанси використання:**
2985+
2986+
- **Економія пам'яті:** об'єкти займають значно менше місця, бо атрибути
2987+
зберігаються у фіксованому масиві, а не в хеш-таблиці `__dict__`.
2988+
- **Швидкість:** доступ до атрибутів у `__slots__` зазвичай трохи швидший.
2989+
- **Відсутність `__dict__`:** ви не зможете динамічно додавати нові атрибути,
2990+
яких немає у списку `__slots__` (якщо тільки не додати `"__dict__"` у сам список).
2991+
- **Слабкі посилання:** якщо ви хочете використовувати `weakref`, потрібно
2992+
явно додати `"__weakref__"` у `__slots__`.
2993+
29742994
**Коротко:**
29752995

2976-
- `__slots__` корисний для великої кількості легковагових об'єктів.
2977-
- Дає memory-оптимізацію і контроль атрибутів.
2978-
- Зменшує гнучкість динамічного додавання полів.
2996+
- `__slots__` корисний для мільйонів легковагових об'єктів (напр. вузли графа).
2997+
- Прибирає `__dict__` і `__weakref__` за замовчуванням.
2998+
- Зменшує гнучкість на користь продуктивності та контролю.
29792999

29803000
</details>
29813001

@@ -3276,12 +3296,28 @@ class C(A, B): ...
32763296
MRO визначає порядок пошуку методів у ієрархії класів.
32773297
У Python використовується алгоритм C3 linearization.
32783298

3299+
**Diamond Problem (Проблема алмазу):**
3300+
Це класичний випадок, коли клас `D` успадковується від `B` та `C`, які обидва
3301+
успадковуються від `A`. MRO гарантує, що `A` буде переглянутий лише після того,
3302+
як будуть переглянуті всі його нащадки (`B` та `C`).
3303+
3304+
```python
3305+
class A: pass
3306+
class B(A): pass
3307+
class C(A): pass
3308+
class D(B, C): pass
3309+
3310+
print(D.mro())
3311+
# [D, B, C, A, object]
3312+
```
3313+
32793314
Переглянути порядок можна через `ClassName.__mro__` або `ClassName.mro()`.
32803315

32813316
**Коротко:**
32823317

32833318
- MRO вирішує, з якого базового класу брати метод.
32843319
- Порядок передбачуваний і формально визначений (C3).
3320+
- Завдяки MRO Python коректно обробляє Diamond Problem.
32853321
- Для cooperative inheritance всі класи мають викликати `super()`.
32863322

32873323
</details>
@@ -3614,7 +3650,9 @@ class Field:
36143650
```python
36153651
from dataclasses import dataclass
36163652
@dataclass(slots=True)
3617-
class User: name: str; active: bool = True
3653+
class User:
3654+
name: str
3655+
active: bool = True
36183656
```
36193657

36203658
**Коротко:**
@@ -4458,7 +4496,6 @@ dir(math)
44584496
- Варто добре знати stdlib перед додаванням сторонніх пакетів.
44594497

44604498
</details>
4461-
44624499
<details>
44634500
<summary>200. Що ви знаєте про пакет `collections`, які ще built-in modules використовувались?</summary>
44644501

@@ -4532,7 +4569,7 @@ random.shuffle(items)
45324569
**Коротко:**
45334570

45344571
- `shuffle` змінює оригінальний список.
4535-
- Працює лише зі списками (mutable sequence).
4572+
- Працює лише з мутабельними послідовностями (наприклад, списками).
45364573
- Для нової копії: `random.sample(items, k=len(items))`.
45374574

45384575
</details>
@@ -4581,7 +4618,7 @@ Virtual environment це ізольоване середовище Python із
45814618

45824619
- Формат простий і сумісний з `pip install -r`.
45834620
- Найкраще фіксувати точні версії для production.
4584-
- Часто генерується з lock-файлів.
4621+
- Часто генерується інструментами (наприклад, `pip-tools` або `poetry export`) з декларативного переліку/lock-файлів.
45854622

45864623
</details>
45874624

@@ -5213,11 +5250,17 @@ CPU-bound задачі переважно витрачають час на об
52135250
`asyncio` запускає event loop, який виконує tasks (coroutines), перемикаючись у
52145251
точках `await` і плануючи готові операції I/O.
52155252

5253+
**Критичне правило:**
5254+
Event loop працює в одному потоці.
5255+
Будь-яка блокувальна операція (`time.sleep()`, синхронні
5256+
запити `requests`, важкі обчислення) зупиняє **весь** цикл
5257+
і всі інші задачі.
5258+
52165259
**Коротко:**
52175260

5218-
- Один потік може обслуговувати багато I/O задач.
5219-
- Планування кооперативне, не preemptive.
5220-
- Блокувальні виклики потрібно виносити з loop.
5261+
- Один потік може обслуговувати багато I/O задач через кооперативність.
5262+
- Планування не витісняє задачі (non-preemptive).
5263+
- Блокувальні виклики вбивають продуктивність asyncio.
52215264

52225265
</details>
52235266

@@ -5266,10 +5309,16 @@ Event loop це планувальник, який відстежує події
52665309
Коли workload CPU-bound або основні бібліотеки блокувальні й не мають async API.
52675310
Також не окупається для простих коротких скриптів.
52685311

5312+
**Вирішення для блокуючого коду:**
5313+
Якщо потрібно використати блокуючу бібліотеку в async-середовищі,
5314+
використовуйте `loop.run_in_executor(None, sync_func)`,
5315+
що запустить її в окремому потоці, не блокуючи event loop.
5316+
52695317
**Коротко:**
52705318

52715319
- Async не прискорює чисті обчислення.
52725320
- Без неблокувальних I/O бібліотек вигода мінімальна.
5321+
- `run_in_executor` допомагає інтегрувати legacy/sync код.
52735322
- Складність async має бути виправдана навантаженням.
52745323

52755324
</details>

0 commit comments

Comments
 (0)