Docker кеширует слои, созданные каждой инструкцией Dockerfile. При повторной сборке, если инструкция и её контекст не изменились, Docker использует сохранённый слой из кеша. Это ускоряет сборку и снижает нагрузку на ресурсы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Конструкция
try...finally используется в случаях, когда нужно гарантировать выполнение кода в finally, независимо от того, возникло исключение или нет. Если файл открыт, его нужно закрыть в любом случае, даже если в процессе работы произойдёт ошибка.
try:
file = open("data.txt", "r")
data = file.read()
finally:
print("Закрываем файл...")
file.close() # Файл закроется даже при ошибке
Если программа работает с базой данных, соединение нужно закрыть, даже если произошла ошибка.
import sqlite3
conn = sqlite3.connect("database.db")
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users") # Ошибка, если таблицы нет
finally:
print("Закрываем соединение с БД...")
conn.close() # Закроет соединение в любом случае
Допустим, есть блокировка файла, которую нужно снять в любом случае.
import threading
lock = threading.Lock()
try:
lock.acquire()
print("Ресурс заблокирован")
# Код, который использует ресурс
finally:
print("Разблокируем ресурс")
lock.release() # Освободит блокировку даже при ошибке
Пример 4: Остановка таймера, даже если произошла ошибка
import time
try:
start_time = time.time()
x = 1 / 0 # Ошибка деления на ноль
finally:
elapsed_time = time.time() - start_time
print(f"Программа выполнялась {elapsed_time:.2f} секунд")
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Процесс последовательного прохода по элементам коллекции (список, строка и др.). Выполняется в цикле for, while, либо через итератор.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6💊1
Пузырьковая сортировка (Bubble Sort) — это один из самых простых, но неэффективных алгоритмов сортировки.
1. Проходим по массиву несколько раз.
2. На каждой итерации сравниваем соседние элементы и меняем их местами, если они идут не в том порядке.
3. После первого прохода наибольший элемент оказывается в конце массива.
4. Повторяем процесс, пока массив не отсортируется.
Количество сравнений в худшем случае:
- На первой итерации:
n-1 сравнений - На второй:
n-2 сравнений - На третьей:
n-3 сравнений - …
- Всего:
(n-1) + (n-2) + ... + 1 = O(n²) Количество обменов (swap) в худшем случае:
- Если массив полностью перевёрнут, на каждой итерации будет максимальное количество перестановок →
O(n²). Если на проходе по массиву не было перестановок, значит массив уже отсортирован.
def bubble_sort(arr):
n = len(arr)
for i in range(n):
swapped = False # Флаг, отслеживающий перестановки
for j in range(n - i - 1):
if arr[j] > arr[j + 1]: # Если элементы в неправильном порядке, меняем местами
arr[j], arr[j + 1] = arr[j + 1], arr[j]
swapped = True
if not swapped:
break # Если перестановок не было, завершаем сортировку
arr = [1, 2, 3, 4, 5] # Уже отсортированный массив
bubble_sort(arr)
print(arr) # [1, 2, 3, 4, 5]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🤔1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥4💊1
Идемпотентность — это свойство операции, при котором повторное выполнение приводит к тому же результату, что и первое.
если операция выполнится повторно (из-за ошибки сети), она не приведёт к неожиданному результату.
позволяет избежать дублирования данных или неожиданных изменений.
гарантирует, что повторные вызовы API не создадут дубликатов.
В веб-разработке идемпотентность важна для API-запросов, чтобы случайные повторные вызовы не привели к непредсказуемым последствиям.
Этот запрос идемпотентен — если отправить его 10 раз, пользователь "Alice" останется тем же.
POST /users { "name": "Alice" }В SQL запросы
SELECT и DELETE часто идемпотентны, а INSERT — нет. DELETE FROM users WHERE id = 5;
Этот запрос идемпотентен — удаление пользователя с ID = 5 несколько раз не изменит систему (если он уже удалён).
INSERT INTO users (name) VALUES ('Alice');Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔2
- JOIN (или INNER JOIN) возвращает только совпадающие строки из обеих таблиц;
- LEFT JOIN возвращает все строки из левой таблицы + совпадающие из правой (если нет совпадения — NULL).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Оконные функции (window functions) — это специальные функции в SQL, которые выполняют вычисления по строкам внутри "окна" (группы строк), но не агрегируют их.
SELECT
id,
месяц,
продавец,
сумма,
SUM(сумма) OVER (PARTITION BY месяц) AS общий_доход_в_месяц
FROM sales;
Пронумеруем продажи каждого продавца в порядке убывания суммы.
SELECT
id,
продавец,
сумма,
ROW_NUMBER() OVER (PARTITION BY продавец ORDER BY сумма DESC) AS номер
FROM sales;
Если два продавца получили одинаковую сумму,
RANK() пропустит следующий номер, а DENSE_RANK() – нет. SELECT
продавец,
сумма,
RANK() OVER (ORDER BY сумма DESC) AS ранг_1,
DENSE_RANK() OVER (ORDER BY сумма DESC) AS ранг_2
FROM sales;
LAG() даёт предыдущее значение, LEAD() – следующее.
SELECT
месяц,
продавец,
сумма,
LAG(сумма) OVER (PARTITION BY продавец ORDER BY месяц) AS предыдущий_месяц,
LEAD(сумма) OVER (PARTITION BY продавец ORDER BY месяц) AS следующий_месяц
FROM sales;
Иногда нужно анализировать не всю группу, а только несколько соседних строк.
SELECT
месяц,
продавец,
сумма,
AVG(сумма) OVER (PARTITION BY продавец ORDER BY месяц ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS скользящее_среднее
FROM sales;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Только один. Python гарантирует, что None — это синглтон, и все ссылки на None указывают на один и тот же объект.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥3
Docker — это инструмент для создания, развертывания и управления контейнерами. Основные команды позволяют управлять образами, контейнерами, сетями и томами.
Образы — это "шаблоны" для создания контейнеров.
Пример: скачиваем Python-образ
docker pull python:3.11
Контейнер — это запущенный процесс на основе образа.
Пример: запустить контейнер с Ubuntu и войти в него
docker run -it ubuntu bash
Пример: остановить и удалить контейнер
docker stop my_app
docker rm my_app
Том (volume) — это способ хранения данных, которые не пропадут при перезапуске контейнера.
Пример: подключить том к контейнеру
docker run -v my_data:/app/data ubuntu
Сети в Docker позволяют контейнерам взаимодействовать друг с другом.
Пример: запустить два контейнера в одной сети
docker network create my_network
docker run -d --network my_network --name app1 ubuntu
docker run -d --network my_network --name app2 ubuntu
Docker Compose позволяет управлять несколькими контейнерами с помощью
docker-compose.yml. Пример
docker-compose.ymlversion: "3"
services:
app:
image: python:3.11
volumes:
- my_data:/app/data
networks:
- my_network
volumes:
my_data:
networks:
my_network:
Запуск
docker compose up -d
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
- Redis — лучше для временного хранения, кэширования, частого доступа;
- PostgreSQL — если хеш должен быть постоянным, использоваться в связях и аналитике.
Если нужны быстродействие и частые запросы — Redis. Если нужна надёжность и история — PostgreSQL.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍1
C++ быстрее Python, потому что:
C++ — компилируемый язык, а Python — интерпретируемый.
C++ работает ближе к "железу", а Python использует абстракции.
C++ использует статическую типизацию, а Python динамическую (дополнительные проверки замедляют код).
Простой пример: сложение чисел в цикле
Python (медленно)
import time
start = time.time()
s = 0
for i in range(10_000_000):
s += i
end = time.time()
print("Python:", end - start, "сек")
Результат
Python: 0.8 сек
C++ (быстро)
#include <iostream>
#include <chrono>
int main() {
auto start = std::chrono::high_resolution_clock::now();
long long s = 0;
for (int i = 0; i < 10000000; i++) {
s += i;
}
auto end = std::chrono::high_resolution_clock::now();
std::cout << "C++: "
<< std::chrono::duration<double>(end - start).count()
<< " сек" << std::endl;
}
Результат
C++: 0.05 сек
Они написаны на C/C++ и работают очень быстро. Пример:
numpy.sum(arr) быстрее, чем sum(list), потому что работает на C. Python код пишется в 2-5 раз быстрее, чем C++. Важно для стартапов и прототипов.
Например, парсинг HTML, обработка логов, работа с API.
Игры, графика (
Unreal Engine, Unity, CryEngine). Разработка операционных систем (Windows, Linux). Быстрая обработка данных, алгоритмы (
sorting, graph, machine learning). Например, если нужно перемножить матрицы размером 10 000 × 10 000, C++ справится в разы быстрее. Python слишком медленный для реального времени, а C++ используется в Arduino, автопилотах, микроконтроллерах.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍9
Это функция, содержащая оператор yield и возвращающая генератор. Она позволяет создавать последовательности "на лету", без загрузки всех элементов в память.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥2
Выбор типа тестирования зависит от целей, стадии разработки и текущих проблем. Чтобы определить, какие тесты нужны, стоит ответить на вопросы:
Что тестируем? (код, API, UI, производительность и т. д.)
Какие риски? (где может сломаться, критичность ошибки)
Какой этап разработки? (новый код, рефакторинг, релиз)
Нужны: Юнит-тесты
Тестируем функции и классы отдельно.
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5 # ✅ Юнит-тест
Нужны: Интеграционные тесты
Проверяем работу всей системы вместе.
def test_api():
response = requests.get("https://api.example.com/data")
assert response.status_code == 200
Нужны: Функциональные и регрессионные тесты
Проверяем ключевые сценарии и старый функционал.
def test_login():
assert login("user", "password") == "Success"
Нужны: UI-тесты (Selenium, Playwright)
Проверяем нажатие кнопок, формы и отображение страниц.
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
assert "Example" in driver.noscript
Нужны: Нагрузочные тесты (Load Testing)
Используем
locust, JMeter, k6, чтобы проверить сколько пользователей выдержит сервер. from locust import HttpUser, task
class MyUser(HttpUser):
@task
def test_homepage(self):
self.client.get("/")
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥5
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊10👍3🔥1
Функция
sleep() из модуля time приостанавливает выполнение программы на заданное количество секунд. Функция
sleep() принимает один аргумент** — число секунд (может быть дробным). import time
print("Программа началась...")
time.sleep(3) # Ожидание 3 секунды
print("3 секунды прошло!")
Ожидание в цикле (имитация загрузки)
for i in range(5, 0, -1):
print(i)
time.sleep(1) # Задержка 1 секунда между выводами
print("Старт!")
Запросы к серверу с паузами (чтобы не забанили)
import time
import requests
for i in range(3):
response = requests.get("https://example.com")
print(f"Запрос {i+1}: статус {response.status_code}")
time.sleep(2) # Ждём 2 секунды перед следующим запросом
Искусственная задержка перед повторной попыткой
for attempt in range(3):
print(f"Попытка {attempt + 1}...")
time.sleep(2) # Ожидание 2 секунды перед новой попыткой
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
1. В базах данных нормализация устраняет избыточность, разбивая таблицы на логические части для предотвращения дублирования.
2. В обработке данных нормализация часто используется для масштабирования значений, чтобы привести их в единый диапазон (например, от 0 до 1).
3. Она улучшает производительность, точность и удобство работы с данными.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤔2
В Python существует несколько типов файловых объектов, которые используются для работы с различными типами данных. Рассмотрим основные виды файловых объектов и их особенности.
Это самый распространённый тип файловых объектов. Такие файлы используются для работы с текстовыми данными и поддерживают строковые операции.
with open("example.txt", "w", encoding="utf-8") as file:
file.write("Привет, мир!") # Записываем текст в файл
with open("example.txt", "r", encoding="utf-8") as file:
content = file.read() # Читаем текст из файла
print(content)Эти файлы используются для работы с двоичными данными (изображениями, видео, аудиофайлами и т. д.).
with open("image.jpg", "rb") as file:
binary_data = file.read() # Читаем файл в бинарном режиме
print(binary_data[:10]) # Выведем первые 10 байтов
with open("copy.jpg", "wb") as file:
file.write(binary_data) # Записываем данные в новый файлЭти объекты представляют собой файловые буферы, которые хранят данные в оперативной памяти, а не на диске.
from io import StringIO
file = StringIO()
file.write("Привет, мир!") # Запись данных в буфер
file.seek(0) # Перемещаем указатель в начало
print(file.read()) # Читаем данные из буфера
Пример работы с
BytesIO:from io import BytesIO
file = BytesIO()
file.write(b"Binary data") # Запись бинарных данных
file.seek(0)
print(file.read()) # Чтение данных
Python позволяет работать с файловыми объектами, полученными из нестандартных источников, например, сокетов или каналов связи (
pipes).import socket
s = socket.socket()
s.connect(("example.com", 80))
s.sendall(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
response = s.makefile("r", encoding="utf-8") # Создание файлового объекта
print(response.readline()) # Читаем первую строку HTTP-ответа
s.close()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Обычно декоратор возвращает функцию или объект, который будет вызываться вместо оригинальной функции. Это может быть обёртка с дополнительной логикой или модифицированная функция.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
В Python существует множество структур данных, которые предоставляют различные способы хранения и управления данными. Они делятся на два основных типа: встроенные структуры данных и пользовательские структуры данных (созданные программистом). Встроенные структуры данных предоставляют готовые инструменты для решения большинства задач, а пользовательские разрабатываются вручную для более сложных или специфичных случаев.
К ним относятся те типы данных, которые изначально встроены в Python. Они обеспечивают простое и удобное управление данными. Вот основные типы:
Массив, который может содержать элементы разных типов. Динамический (размер меняется), упорядоченный (элементы хранятся в порядке добавления).
my_list = [1, "hello", 3.14]
print(my_list[1]) # "hello"
Похож на список, но неизменяемый. Используется для данных, которые не должны быть изменены.
my_tuple = (10, 20, 30)
print(my_tuple[0]) # 10
Неупорядоченная коллекция уникальных элементов. Удобно для работы с множествами (поиск пересечений, объединений и т.д.).
my_set = {1, 2, 3, 2}
print(my_set) # {1, 2, 3}Хранит пары ключ-значение. Очень эффективен для быстрого поиска данных по ключу.
my_dict = {"name": "Alice", "age": 25}
print(my_dict["name"]) # AliceЭти структуры создаются с помощью классов или других механизмов, доступных в Python. Они применяются для решения задач, которые не могут быть эффективно выполнены встроенными средствами.
Принцип работы: LIFO (последним пришел — первым ушел). Реализуется через список или
collections.deque. stack = []
stack.append(10) # Добавление
stack.append(20)
print(stack.pop()) # Удаление последнего элемента (20)
Принцип работы: FIFO (первым пришел — первым ушел). Реализуется через
collections.deque или библиотеку queue. from collections import deque
queue = deque()
queue.append(10)
queue.append(20)
print(queue.popleft()) # 10
Элементы связаны друг с другом через указатели. Гибче массивов, но сложнее в реализации.
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def append(self, data):
if not self.head:
self.head = Node(data)
else:
current = self.head
while current.next:
current = current.next
current.next = Node(data)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Задача NP-полная, если:
- она принадлежит классу NP (решение проверяется за полиномиальное время);
- она неизвестна как решаемая за полиномиальное время, но если бы нашлось решение для одной NP-полной задачи — решились бы и остальные;
- она сводится к другим NP-полным задачам.
Примеры: задача коммивояжёра, рюкзака, раскраски графа.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🤔3🔥2