Похожие презентации:
Консультация
1. Консультация
2. Что за методы setup и teardown?
• import unittest• class MyTestCase(unittest.TestCase):
def setUp(self):
self.file = open('test.txt', 'w')
self.file.write('hello')
self.file.close()
def tearDown(self):
import os
os.remove('test.txt')
• def test_file(self):
with open('test.txt') as f:
data = f.read()
self.assertEqual(data,
'hello')
• if __name__ == '__main__':
unittest.main()
3. Что за методы setup и teardown?
• setUp(self):• Перед каждым тестом
• tearDown(self):
• После каждого теста
4. Для чего используется модуль socket в Python?
• import socket5. Как установить соединение с сервером с помощью socket?
6. Как установить соединение с сервером с помощью socket?
• Сначала создать объект сокета:• import socket
• s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
• Затем подключиться:
• s.connect(('urgu.org', 80))
7. Для чего используется модуль socket в Python?
• Модуль socket позволяетсоздавать сетевые
соединения, обмениваться
данными между
программами по сети с
помощью протоколов TCP и
UDP
8. Какие шаги нужно выполнить для скачивания веб-страницы по адресу http://urgu.org/150 с помощью TCP-клиента?
9. Какие шаги нужно выполнить для скачивания веб-страницы по адресу http://urgu.org/150 с помощью TCP-клиента?
• Создать socket• Отправить HTTP-запрос
методом GET
• Подключиться к серверу
(connect)
• Получить ответ с помощью
recv
• Закрыть соединение
10. Какие шаги нужно выполнить для скачивания веб-страницы по адресу http://urgu.org/150 с помощью TCP-клиента?
• import socket• # 1. Создаем socket
• s = socket.socket()
• # 2. Подключаемся к серверу urgu.org по
порту 80(Почему 80??)
• s.connect(('urgu.org', 80))
• # 3. Отправляем HTTP GET-запрос
• request = 'GET /150 HTTP/1.1\r\nHost:
urgu.org\r\nConnection: close\r\n\r\n'
• s.sendall(request.encode())
• # 4. Получаем ответ
• response = b""
• while True:
data = s.recv(4096)
if not data:
break
response += data
• # 5. Закрываем соединение
• s.close()
• # 6. Выводим полученные данные
• print(response.decode('utf-8', errors='replace'))
11. Чем отличается send от sendall?
12. Чем отличается send от sendall?
• Метод send может отправитьне все байты из переданных
(возвращает количество
отправленных).
• sendall отправляет все
данные или вызывает
исключение.
• Нужно использовать sendall,
если важно, чтобы были
отправлены все данные.
13. Как работает recv? В чём его особенность?
14. Как работает recv? В чём его особенность?
• recv• Является блокирующим
методом
• Ждёт, пока не появятся данные
в сети
• Возвращает не более указанного
количества байт
15. Какие есть варианты указания размера пакета данных при передаче по сети?
16. Какие есть варианты указания размера пакета данных при передаче по сети?
• Использовать фиксированныйразмер пакета (например,
всегда 1024 байта)
• Использовать специальный
ограничитель (разделитель)
между пакетами
• Указывать размер данных в
начале пакета (например, в
первых байтах)
• Контекстный способ, когда
окончание передачи
определяется из данных
протокола (например, конец
HTTP-заголовков)
17. Какие есть варианты указания размера пакета данных при передаче по сети?
• Фиксированный размер пакета• Размер данных в начале пакета
• # Отправитель
• sock.sendall(data.ljust(1024, b'\x00'))
• import struct
• # Получатель
• received = sock.recv(1024)
# Отправитель
msg = b'hello, world'
length = struct.pack('!I', len(msg)) # 4 байта, network order
sock.sendall(length + msg)
# Получатель
raw_length = sock.recv(4)
msg_length = struct.unpack('!I', raw_length)[0]
data = sock.recv(msg_length)
18. Какие есть варианты указания размера пакета данных при передаче по сети?
• Использование специальногоразделителя
• Контекстный способ (пример с
HTTP)
• # Отправитель
• msg = b'Hello, world\n'
• sock.sendall(msg)
• # Получатель (чтение заголовков
HTTP)
• headers = b''
• while b'\r\n\r\n' not in headers:
headers += sock.recv(1)
• # После headers можно читать тело,
если оно есть
• # Получатель
• buffer = b''
• while not buffer.endswith(b'\n'):
buffer += sock.recv(1)
19. Как правильно закрыть соединение после окончания передачи данных через socket?
20. Как правильно закрыть соединение после окончания передачи данных через socket?
• s.shutdown(socket.SHUT_RDWR)• s.close()
• shutdown закрывает соединение на
чтение и запись
• close освобождает ресурсы сокета
21. Чем различаются IO-bound и CPU-bound задачи? Привести примеры каждой
22. Чем различаются IO-bound и CPU-bound задачи? Привести примеры каждой
• IO-bound задачи ограниченыскоростью ввода-вывода
• Например, чтение/запись файлов,
сетевые запросы
• CPU-bound — скоростью
вычислений процессора
• Например, вычисление
факториала, рендеринг
изображения
23. Чем различаются IO-bound и CPU-bound задачи? Привести примеры каждой
• # IO-bound: загрузка данных изинтернета
• import requests
• # CPU-bound: вычисление факториала
• def cpu_bound_task():
result = 1
• def io_bound_task():
for i in range(1, 100000):
response =
result *= i
requests.get('https://example.com')
return result
return response.text
24. Какой привычный подход применяют для ускорения обработки множества IO-bound задач? Почему он помогает?
25. Какой привычный подход применяют для ускорения обработки множества IO-bound задач? Почему он помогает?
• Используют многопоточность(threading) или пул потоков
(thread pool).
• Это помогает, так как при
ожидании IO (например,
ответа сервера) другие
потоки могут выполняться.
26. Какой привычный подход применяют для ускорения обработки множества IO-bound задач? Почему он помогает?
• # Использование ThreadPoolExecutorдля параллельных сетевых запросов
• import concurrent.futures
• import requests
• urls = ['https://example.com',
'https://python.org']
• def fetch(url):
return requests.get(url).text
• with
concurrent.futures.ThreadPoolExecutor() as
executor:
results = list(executor.map(fetch, urls))
27. Что такое асинхронное программирование? В чём его отличие от многопоточности?
28. Что такое асинхронное программирование? В чём его отличие от многопоточности?
• Асинхронноепрограммирование:
• Способ управления задачами,
когда выполнение операций
может приостанавливаться и
возобновляться
• Без выделения отдельных
потоков)
• Отличие:
• Задачи в одном потоке
переключаются между собой
при ожидании IO, экономя
ресурсы
29. Что такое асинхронное программирование? В чём его отличие от многопоточности?
• import asyncio• async def async_task():
await asyncio.sleep(1)
print("Task complete")
• asyncio.run(async_task())
30. Что такое event loop, coroutine, ключевые слова async и await? Как они связаны между собой?
31. Что такое event loop, coroutine, ключевые слова async и await? Как они связаны между собой?
• Event loop (цикл событий)управляет исполнением
coroutines (корутин)
• Всё вместе позволяет
реализовать асинхронное
выполнение задач
• Корутины задаются с
помощью async
• await позволяет
приостанавливать
выполнение до получения
результата
32. Что такое event loop, coroutine, ключевые слова async и await? Как они связаны между собой?
• import asyncio• async def say_hello():
await asyncio.sleep(1)
print("Hello!")
• asyncio.run(say_hello())
33. Как получить возвращаемое значение из coroutine?
34. Как получить возвращаемое значение из coroutine?
• Возвращаемое значение изcoroutine получается после её
выполнения с помощью await
или через event loop
• import asyncio
• async def compute():
await asyncio.sleep(1)
return 42
• result = asyncio.run(compute())
• print(result) # 42
35. Для чего используется функция asyncio.wait?
36. Для чего используется функция asyncio.wait?
• asyncio.wait позволяетодновременно запустить
несколько корутин и
дождаться их завершения
37. Для чего используется функция asyncio.wait?
• async def foo():await asyncio.sleep(1)
return 'foo'
• async def bar():
await asyncio.sleep(2)
return 'bar'
• async def main():
tasks = [foo(), bar()]
done, pending = await
asyncio.wait(tasks)
for task in done:
print(task.result())
• asyncio.run(main())
38. Зачем используются конструкции async for и async with?
39. Зачем используются конструкции async for и async with?
• Они позволяют асинхронноработать с итераторами и
контекстными менеджерами
• Например, для потоковой
обработки данных или
работы с соединениями
40. Зачем используются конструкции async for и async with?
• import asyncio• class AsyncIterator:
def __init__(self):
self.count = 0
def __aiter__(self):
return self
• async def main():
async for value in AsyncIterator():
print(value) # 1, 2, 3
• async def __anext__(self):
if self.count < 3:
await asyncio.sleep(1)
self.count += 1
return self.count
else:
raise StopAsyncIteration
• asyncio.run(main())
41. Зачем нужна сериализация данных в программировании? Приведите примеры ситуаций, когда она необходима
42. Зачем нужна сериализация данных в программировании? Приведите примеры ситуаций, когда она необходима
• Сериализация нужна длясохранения состояния
объектов в файл или
передачи их по сети, чтобы
потом восстановить эти
объекты
• Например, чтобы сохранить
результаты программы между
запусками, передать данные
по интернету или отправить
их в другую программу
43. Зачем нужна сериализация данных в программировании? Приведите примеры ситуаций, когда она необходима
• import json• data = {"name": "Ivan", "age": 30}
• with open("data.json", "w") as f:
json.dump(data, f)
44. Назови основные способы хранения сериализованных данных в Python и объясни разницу между pickle, json и sqlite
45. Назови основные способы хранения сериализованных данных в Python и объясни разницу между pickle, json и sqlite
• pickle —• Сериализует любые объекты
Python, но формат бинарный и
небезопасный
• json —
• Сохраняет только стандартные
типы (словарь, список, строки,
числа), но читабельный и
кросс-языковой
• sqlite —
• База данных, где данные
хранятся в виде таблиц,
поддерживает запросы,
подходит для сложных структур
и больших объёмов
46. Назови основные способы хранения сериализованных данных в Python и объясни разницу между pickle, json и sqlite
• # pickle• d = {"a": 1}
• # sqlite
• conn = sqlite3.connect('example.db')
• with open("data.pkl", "wb") as f:
pickle.dump(d, f)
• c = conn.cursor()
• c.execute('CREATE TABLE IF NOT EXISTS
users (name TEXT, age INTEGER)')
• c.execute('INSERT INTO users VALUES (?, ?)',
("Ivan", 30))
• conn.commit()
• conn.close()
• # json
• with open("data.json", "w") as f:
json.dump(d, f)
47. Какие недостатки и риски есть у pickle?
48. Какие недостатки и риски есть у pickle?
• Pickle небезопасен —• Можно исполнить вредоносный
код при десериализации.
• # Никогда не делай так с недоверенными
файлами!
• with open("data.pkl", "rb") as f:
• Так же он не совместим между
разными версиями Python, а
его формат не читаем вне
Python
obj = pickle.load(f)
• # опасно: могут быть вредоносные
команды
49. Что такое валидация сериализованных данных? Зачем она нужна?
50. Что такое валидация сериализованных данных? Зачем она нужна?
• Валидация — это проверка,что данные соответствуют
ожидаемому формату и типу
• Нужна, чтобы избежать
ошибок и защищаться от
некорректных/вредоносных
данных при десериализации
51. Что такое валидация сериализованных данных? Зачем она нужна?
• def validate(data):return isinstance(data, dict) and
"name" in data and "age" in data
• with open("data.json") as f:
loaded = json.load(f)
if validate(loaded):
print("OK")
else:
print("Ошибка данных")
52. Как обеспечивают восстановление данных после сбоев при сериализации?
53. Как обеспечивают восстановление данных после сбоев при сериализации?
• Используют:• Резервные копии (backup)
• Промежуточные файлы
• Журналирование изменений
или транзакции (особенно в
базах данных), чтобы не
потерять/не повредить
данные при сбоях
54. Как обеспечивают восстановление данных после сбоев при сериализации?
• data = {"test": 123}• with open("datatmp.json", "w")
as f:
json.dump(data, f)
• os.replace("datatmp.json", "data.json")
• # Заменяет файл только если запись
прошла успешно
55. Что такое append log (журналирование изменений)? Почему это важно для сериализации?
56. Что такое append log (журналирование изменений)? Почему это важно для сериализации?
• Append log —• Файл, куда все изменения
записываются
последовательным
добавлением
• Это позволяет восстановить
последнее состояние после
сбоя и проводить откат
57. Что такое append log (журналирование изменений)? Почему это важно для сериализации?
• import json• logentry = {"action": "update", "user": "Ivan"}
• with open("log.txt", "a") as f:
f.write(json.dumps(logentry) + "\n")
• # Восстановление из лога
• with open("log.txt") as f:
for line in f:
entry = json.loads(line.strip())
print(entry)
58. Какие основные объекты можно профилировать в приложении? Приведите примеры
59. Какие основные объекты можно профилировать в приложении? Приведите примеры
• Время выполнения,потребление памяти,
операции ввода-вывода (IO),
использование процессора и
других ресурсов
60. Какие основные объекты можно профилировать в приложении? Приведите примеры
• import time• import sys
• start = time.time()
• print("Память:", sys.getsizeof(a))
• a = x for x in range(1000000)
• # считаем время и память
• print("Время:", time.time() - start)
61. Чем отличаются семплирующее профилирование и инструментирование? Назови плюсы и минусы
62. Чем отличаются семплирующее профилирование и инструментирование? Назови плюсы и минусы
• Семплирующеепрофилирование
периодически "снимает"
статистику во время работы
программы, не сильно
замедляет выполнение, но
менее точно
• Инструментирование
встраивает код сбора
статистики прямо в целевые
функции, точнее, но может
значительно замедлить
выполнение
63. Чем отличаются семплирующее профилирование и инструментирование? Назови плюсы и минусы
• # Пример профилирования черезвстроенный декоратор
(инструментирование)
• def myprofiler(func):
def wrapper(*args, **kwargs):
import time
start = time.time()
res = func(*args, **kwargs)
print(f"Время работы {func.name}:
{time.time() - start}")
return res
return wrapper
• @myprofiler
• def work():
sum(range(1000000))
• work()
64. Назовите популярные инструменты профилирования в Python, для чего они нужны?
65. Назовите популярные инструменты профилирования в Python, для чего они нужны?
• timeit —• Для измерения времени работы
кода
• Декоратор времени —
• Свой декоратор для замера
времени
• cProfile, profile —
• Встроенные инструменты для
детального профилирования
функций
• statprof —
• Сторонний для семплирующего
профиля
66. Назовите популярные инструменты профилирования в Python, для чего они нужны?
• import timeit• print(timeit.timeit("sum(range(1000))",
number=1000))
• import cProfile
• def func():
sum(range(10000))
• cProfile.run('func()')
Программирование