Python | Вопросы собесов
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
Show more📈 Analytical overview of Telegram channel Python | Вопросы собесов
Channel Python | Вопросы собесов (@python_easy_ru) in the Russian language segment is an active participant. Currently, the community unites 12 638 subscribers, ranking 9 922 in the Technologies & Applications category and 51 155 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 12 638 subscribers.
According to the latest data from 13 October, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -115 over the last 30 days and by -6 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 6.04%. Within the first 24 hours after publication, content typically collects 4.18% reactions from the total number of subscribers.
- Post reach: On average, each post receives 763 views. Within the first day, a publication typically gains 528 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 2.
- Thematic interests: Content is focused on key topics such as ставь, модуль, строка, docker, alice.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy
Контакт для рекламы: @sendme_ads”
Thanks to the high frequency of updates (latest data received on 14 October, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
n-1 сравнений
- На второй: n-2 сравнений
- На третьей: n-3 сравнений
- …
- Всего: (n-1) + (n-2) + ... + 1 = O(n²)
Количество обменов (swap) в худшем случае:
- Если массив полностью перевёрнут, на каждой итерации будет максимальное количество перестановок → O(n²).
🚩Оптимизированная пузырьковая сортировка (`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]
Ставь 👍 и забирай 📚 Базу знанийpublic void verifyLoginWithValidCredentials() { ... }
// Плохо
public void test1() { ... }
Описательные названия помогают быстро понять, что проверяет тест, без необходимости изучения его внутренней логики.
2. Применяйте Page Object Model (POM)
Page Object Model позволяет отделить логику теста от структуры веб-страницы, что делает код более модульным и удобным для поддержки при изменениях интерфейса.
Пример использования:
// Класс
Page Object
public class LoginPage {
private By usernameField = By. id("username");
private By passwordField = By. id("password");
private By loginButton = By. id("loginBtn");
public void enterUsername(String username) {
driver.findElement(usernameField).sendKeys(username);
}
public void enterPassword(String password) {
driver.findElement(passwordField).sendKeys(password);
}
public void clickLoginButton() {
driver.findElement(loginButton).click();
}
}
// Тестовый сценарий
LoginPage loginPage = new LoginPage(driver);
loginPage.enterUsername("john.doe");
loginPage.enterPassword("password123");
loginPage.clickLoginButton();
POM способствует повторному использованию кода и улучшает читаемость тестов.
3. Используйте параметризацию и data-driven подход
Параметризованные тесты позволяют запускать один и тот же сценарий с различными входными данными, что увеличивает охват тестирования без дублирования кода.
@ ParameterizedTest
@ CsvSource({"john.doe, password123", "jane.smith, test@123"})
public void verifyLogin(String username, String password) {
LoginPage loginPage = new LoginPage(driver);
loginPage.enterUsername(username);
loginPage.enterPassword(password);
loginPage.clickLoginButton();
}
Этот подход делает тесты более гибкими и масштабируемыми.
4. Следуйте принципу AAA (Arrange, Act, Assert)
Структурируйте тесты в три этапа:
Arrange: подготовка данных и окружения.
Act: выполнение действия.
Assert: проверка результата.
Пример:
@ Test
public void testAddition() {
// Arrange
Calculator calculator = new Calculator();
// Act
int result = calculator.add(2, 3);
// Assert
assertEquals(5, result);
}
Этот подход делает тесты более организованными и легко читаемыми.
5. Логирование и отчетность
Добавляйте логирование в тесты для диагностики проблем:
log. info("Entering username: " + username);
log. info("Clicking on the login button");
Интеграция инструментов отчетности (например, Allure) помогает визуализировать результаты тестов и быстро выявлять ошибки.
6. Регулярные ревью кода
Проводите регулярные ревью автотестов для повышения качества кода. Это помогает выявить потенциальные проблемы, улучшить читаемость и обеспечить соблюдение стандартов кодирования.
7. Автоматизация и CI/CD
Используйте инструменты автоматизации (Maven, Gradle) для запуска тестов в рамках CI/CD пайплайнов. Это ускоряет процесс разработки и обеспечивает стабильность приложения на всех этапах.
Хотите узнать больше? Присоединяйтесь уже сегодня (20:00 Мск) к бесплатному открытому уроку!
🔗 Зарегистрируйтесь на первый открытый урок по ссылке.База данных (company_db) ├── Схема: public (по умолчанию) │ ├── Таблица: employees │ ├── Таблица: departments ├── Схема: hr │ ├── Таблица: employees │ ├── Таблица: salaries ├── Схема: sales │ ├── Таблица: customers │ ├── Таблица: orders🚩Как создавать и использовать схемы? Создание схемы (
CREATE SCHEMA)
CREATE SCHEMA hr; -- Создаём схему "hr"
Создание таблицы внутри схемы
CREATE TABLE hr.employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
position VARCHAR(50)
);
Выбор схемы по умолчанию
SET search_path TO hr;
🚩Где полезны схемы?
🟠Разделение данных по модулям
Если в БД хранятся разные области бизнеса (кадры, продажи, финансы), их можно разделить по схемам:
- hr.employees, hr.salaries
- sales.orders, sales.customers
🟠Разные версии одной БД
Например, в PostgreSQL можно создать схему dev для тестов:
- dev.users — тестовая версия таблицы
- prod.users — продакшен-версия
🟠Безопасность и доступ пользователей
Можно дать доступ к разным схемам разным пользователям:
GRANT USAGE ON SCHEMA hr TO hr_manager;
GRANT SELECT ON ALL TABLES IN SCHEMA hr TO hr_manager;
Ставь 👍 и забирай 📚 Базу знанийJOIN, используя альтернативные методы.
🚩Использование подзапросов (`SELECT` внутри `SELECT`)
Подзапрос (subquery) позволяет выбрать данные из одной таблицы, используя данные из другой.
Допустим, у нас есть две таблицы:
employees (id, name, department_id)
departments (id, name)
SELECT name,
(SELECT name FROM departments WHERE id = employees.department_id) AS department_name
FROM employees;
🚩Использование `IN` или `EXISTS`
Можно фильтровать данные из одной таблицы, проверяя наличие значений в другой.
SELECT name
FROM employees
WHERE department_id IN (SELECT id FROM departments);
🚩Объединение данных через `UNION`
Если таблицы имеют схожие колонки, можно объединить их с UNION.
SELECT id, name, email FROM users_old
UNION
SELECT id, name, email FROM users_new;
🚩Использование `CROSS JOIN` через `WHERE`
Хотя CROSS JOIN делает декартово произведение, его можно фильтровать WHERE, имитируя INNER JOIN.
SELECT e.name, d.name AS department
FROM employees e, departments d
WHERE e.department_id = d.id;
Ставь 👍 и забирай 📚 Базу знанийpackage) в Python — это набор модулей, объединённых в одну директорию. Главное отличие от обычной папки — наличие файла __init__.py, который делает директорию пакетом.
🚩Как создать пакет?
Допустим, мы хотим создать пакет math_utils с модулями для работы с числами.
/my_project
/math_utils ← Это пакет
__init__.py ← Делаем директорию пакетом
arithmetic.py ← Модуль с функциями сложения/вычитания
geometry.py ← Модуль с функциями для работы с фигурами
main.py ← Основной файл программы
Код в arithmetic.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
Код в geometry.py
def square_area(side):
return side * side
Код в __init__.py
from .arithmetic import add, subtract
from .geometry import square_area
Теперь можно импортировать функции прямо из пакета:
from math_utils import add, square_area
print(add(2, 3)) # 5
print(square_area(4)) # 16
🚩Импорт модулей из пакета
Импортируем весь пакет (с __init__.py)
from math_utils import add, square_area
Импортируем конкретный модуль
from math_utils import arithmetic
print(arithmetic.add(3, 5))
Импортируем конкретную функцию из модуля
from math_utils.arithmetic import add
print(add(3, 5))
🚩Как работают пакеты в Python?
Python ищет пакеты по sys.path
import sys
print(sys.path) # Пути, где Python ищет модули
Если Python не находит пакет, можно добавить путь вручную:
import sys
sys.path.append("/path/to/my_project")
Можно создавать вложенные пакеты
/my_project
/math_utils
__init__.py
/advanced
__init__.py
calculus.py
Импорт:
from math_utils.advanced.calculus import derivative
Ставь 👍 и забирай 📚 Базу знанийkeys), так как доступ к ним O(1).
data = {"name": "Alice", "age": 25, "city": "New York"}
# Проверяем, есть ли ключ "age"
if "age" in data:
print("Ключ найден!")
Вывод
Ключ найден!Не надо проверять так
if data.get("age") is not None: # ❌ Работает, но `in` быстрее
🟠Проверка наличия значения (`in values()`)
Если нужно проверить значение, используем values()
if 25 in data.values():
print("Значение найдено!")
Вывод
Значение найдено!🟠Проверка и ключа, и значения (`items()`) Если нужно проверить пару (ключ, значение)
if ("age", 25) in data.items():
print("Пара (ключ, значение) найдена!")
Ставь 👍 и забирай 📚 Базу знанийfilter() — это встроенная функция Python, которая отбирает элементы из последовательности по заданному условию.
filter(function, iterable)
🚩Как работает `filter()`?
Пример 1: Фильтрация чётных чисел
numbers = [1, 2, 3, 4, 5, 6]
# Оставляем только чётные числа
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers)) # [2, 4, 6]
Пример 2: Фильтрация строк по длине
words = ["apple", "kiwi", "banana", "cherry"]
# Оставляем только слова длиной больше 5 символов
long_words = filter(lambda word: len(word) > 5, words)
print(list(long_words)) # ['banana', 'cherry']
Пример 3: Фильтрация None и пустых значений
values = [None, 0, "", "hello", 42, [], {}]
# Оставляем только "истинные" значения
filtered_values = filter(None, values)
print(list(filtered_values)) # ['hello', 42]
Пример 4: Использование filter() с def
def is_positive(n):
return n > 0
numbers = [-5, -2, 0, 3, 7, -1]
positive_numbers = filter(is_positive, numbers)
print(list(positive_numbers)) # [3, 7]
🚩Чем `filter()` лучше `for` + `if`?
Более короткий и читаемый код
# С `filter()`
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
# С `for` + `if`
even_numbers = [x for x in numbers if x % 2 == 0]
Ставь 👍 и забирай 📚 Базу знанийdef add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5 # ✅ Юнит-тест
🟠Соединяем модули или работаем с API
Нужны: Интеграционные тесты
Проверяем работу всей системы вместе.
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 (например, фронтенд на React)
Нужны: UI-тесты (Selenium, Playwright)
Проверяем нажатие кнопок, формы и отображение страниц.
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://example.com")
assert "Example" in driver.title
🟠Если проект должен выдерживать большую нагрузку
Нужны: Нагрузочные тесты (Load Testing)
Используем locust, JMeter, k6, чтобы проверить сколько пользователей выдержит сервер.
from locust import HttpUser, task
class MyUser(HttpUser):
@task
def test_homepage(self):
self.client.get("/")
Ставь 👍 и забирай 📚 Базу знанийГорячие вакансии с привлекательными офферами для джуниор разработчиков, аналитиков, дизайнеров и QA-специалистов.👉 ПОДПИСАТЬСЯ 🔺СТАЖИРОВКИ
Стажировки для начинающих специалистов в IT независимо от возраста!👉 ПОДПИСАТЬСЯ 🔺IT interns
Свежие стажировки для junior специалистов в топовых компании России и мира👉 ПОДПИСАТЬСЯ 🔺Junojobs
Вакансии и стажировки для junior-разработчиков на удалёнке.👉 ПОДПИСАТЬСЯ 🔺БИГТЕХ
Junior вакансии и стажировки в крупнейших IT-компаниях мира: NVidia, Apple, T-банк, Яндекс, Google и т. д.👉 ПОДПИСАТЬСЯ 🔺Ква инженер - QA junior
Отборные джун вакансии и стажировки для QA, тестировщиков.👉 ПОДПИСАТЬСЯ
threading, но из-за GIL (Global Interpreter Lock) потоки не могут выполняться параллельно на нескольких ядрах.
🟠Модуль `threading` (многопоточность, но с GIL)
Модуль threading позволяет запускать несколько потоков (threads) в одном процессе.
import threading
import time
def task(name):
print(f"{name} начал работу")
time.sleep(2) # Имитация задержки
print(f"{name} завершил работу")
# Создаём два потока
t1 = threading.Thread(target=task, args=("Поток 1",))
t2 = threading.Thread(target=task, args=("Поток 2",))
t1.start()
t2.start()
t1.join()
t2.join()
print("Все потоки завершены")
Вывод
Поток 1 начал работу Поток 2 начал работу (пауза 2 секунды) Поток 1 завершил работу Поток 2 завершил работу Все потоки завершены🟠Модуль `multiprocessing` (настоящая параллельность) В отличие от
threading, модуль multiprocessing создаёт отдельные процессы, которые могут выполняться на разных ядрах процессора.
import multiprocessing
import time
def task(name):
print(f"{name} начал работу")
time.sleep(2)
print(f"{name} завершил работу")
if __name__ == "__main__":
p1 = multiprocessing.Process(target=task, args=("Процесс 1",))
p2 = multiprocessing.Process(target=task, args=("Процесс 2",))
p1.start()
p2.start()
p1.join()
p2.join()
print("Все процессы завершены")
🟠Модуль `concurrent.futures` (более удобный API)
Этот модуль позволяет легко управлять потоками (ThreadPoolExecutor) и процессами (ProcessPoolExecutor).
from concurrent.futures import ThreadPoolExecutor
import time
def task(n):
time.sleep(2)
return f"Готово: {n}"
with ThreadPoolExecutor(max_workers=2) as executor:
results = executor.map(task, [1, 2, 3])
for result in results:
print(result)
Пример ProcessPoolExecutor (процессы)
from concurrent.futures import ProcessPoolExecutor
def square(n):
return n * n
with ProcessPoolExecutor() as executor:
results = executor.map(square, [1, 2, 3, 4])
print(list(results)) # [1, 4, 9, 16]
🟠Модуль `asyncio` (асинхронность, не потоки!)
Модуль asyncio не создаёт потоки или процессы, а работает через "корутины" и цикл событий (event loop).
import asyncio
async def task():
print("Начало")
await asyncio.sleep(2) # Не блокирует другие задачи
print("Конец")
async def main():
await asyncio.gather(task(), task())
asyncio.run(main())
Ставь 👍 и забирай 📚 Базу знаний