Python | Вопросы собесов
13.4K subscribers
18 photos
1 file
319 links
Разбираем вопросы с собеседований на Python разработчика. Django, Flask, FastApi

Реклама: @easyoffer_adv
Решай тесты - t.me/+20tRfhrwPpM4NDQy

Нарешивай задачи - t.me/+nsl4meWmhfQwNDVi
Ищи работу - t.me/+cXGKkrOY2-w3ZTky
Download Telegram
Какие есть паттерны программирования ?
Спросят с вероятностью 10%

Паттерны программирования - это bewконцептуальные решения типичных проблем, возникающих при разработке ПО. Они представляют собой bewпрактики, которые помогают создавать более эффективные, гибкие и поддерживаемые программы. Вот несколько основных:

1️⃣ Порождающие(Creational Patterns):
- Фабричный метод (Factory Method)
- Абстрактная фабрика (Abstract Factory)
- Строитель (Builder)
- Прототип (Prototype)
- Одиночка (Singleton)

2️⃣ Структурные(Structural Patterns):
- Адаптер (Adapter)
- Мост (Bridge)
- Компоновщик (Composite)
- Декоратор (Decorator)
- Фасад (Facade)
- Приспособленец (Flyweight)
- Заместитель (Proxy)

3️⃣ Поведенческие(Behavioral Patterns):
- Цепочка обязанностей (Chain of Responsibility)
- Команда (Command)
- Итератор (Iterator)
- Посредник (Mediator)
- Хранитель (Memento)
- Наблюдатель (Observer)
- Состояние (State)
- Стратегия (Strategy)
- Шаблонный метод (Template Method)
- Посетитель (Visitor)

Это только небольшой обзор паттернов. Каждый из них решает определенный типичный набор проблем и может быть применен в соответствующих ситуациях. Использование паттернов программирования помогает создавать более гибкий, поддерживаемый и расширяемый код.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Какой тип данных можно использовать в качестве ключа в словаре Python, при условии что он должен быть неизменяемым и хешируемым?
Anonymous Quiz
5%
Списки
8%
Словари
76%
Кортежи, если все их элементы хешируемы
11%
Множества
Чем отличаются классы от миксинов (mixin) ?
Спросят с вероятностью 7%

Классы и миксины (mixin) - это два различных концепта, но они могут быть взаимосвязаны и использоваться вместе. Вот основные различия:

1️⃣ Классы:
- являются основными строительными блоками объектно-ориентированного программирования.
- Они определяют поведение и состояние объектов, которые создаются на основе этих классов.
- Может быть абстрактным или конкретным, иметь атрибуты, методы, конструкторы и другие спецификации.
- Их экземпляры могут быть созданы непосредственно из определенного класса.

2️⃣ Миксины (mixin):
- Классы, которые предназначены для повторного использования функциональности в различных классах.
- Они обычно содержат методы или атрибуты, которые могут быть включены в другие классы.
- Обычно не предназначены для создания экземпляров, они используются для наследования и комбинирования функциональности с другими классами.
- Их спользование позволяет избежать дублирования кода и создать гибкие и модульные системы.

Основное различие между классами и миксинами заключается в их предназначении и использовании: классы являются основными элементами программирования, в то время как миксины - это инструмент для повторного использования кода и комбинирования функциональности между классами. Иногда множественное наследование и использование миксинов позволяют создавать более гибкие и выразительные программы.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Какую связь использовать для расширения стандартного юзера ?
Спросят с вероятностью 7%

Для расширения стандартной модели пользователя (User) обычно используется связь "один к одному" (OneToOne). Это позволяет создать дополнительную модель, которая будет связана с моделью пользователя и содержать дополнительные поля и методы, необходимые вашему приложению. Для этого вы можете создать новую модель, которая будет содержать информацию, которую вы хотите добавить к стандартной модели пользователя, и затем создать связь "один к одному" между новой и моделью пользователя.
from django.contrib.auth.models import User
from django.db import

class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
# Дополнительные поля для расширения модели пользователя
date_of_birth = models.DateField()
avatar = models.ImageField(upload_to='avatars/')

# Дополнительные методы и свойства
def get_full_name(self):
return f'{self.user.first_name} {self.user.last_name}'

def str(self):
return self.user.username


В этом примере UserProfile- это модель, которая расширяет стандартную модель пользователя (User) с дополнительными полями date_of_birthи avatar. Связь OneToOneField указывает на то, что каждый объект UserProfile связан с одним и только одним объектом User.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Что означает querySet() ленивые ?
Спросят с вероятностью 7%

"Ленивый" QuerySet означает, что выполнение запроса к базе данных откладывается до того момента, когда данные фактически понадобятся в вашем коде. Когда вы создаете его, например, с помощью метода filter() или all(), Django не выполняет фактический запрос к базе данных. Вместо этого он создает объект QuerySet, который представляет собой запрос к базе данных и может быть дальше модифицирован (фильтрован, сортирован и т.д.).

Только когда вы начинаете использовать результаты этого QuerySet, например, вызывая метод list(), count() или проходя по нему в цикле, Django выполняет запрос к базе данных и возвращает результаты.
# Создаем QuerySet, но запрос к базе данных не выполняется
queryset = MyModel.objects.filter(status='active')

# Запрос к базе данных выполняется только в этот момент
results = list(queryset)

Такое поведение называется "ленивой загрузкой" (lazy loading), и оно помогает избежать избыточных запросов к базе данных и оптимизировать производительность вашего приложения, так как запросы выполняются только в том случае, когда данные действительно нужны.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Как реализован many to many в Django ?
Спросят с вероятностью 7%

Связь many-to-many реализуется с помощью специального типа поля - ManyToManyField. Это поле позволяет связать одну модель с несколькими объектами другой модели и наоборот без создания дополнительной промежуточной модели.

Для создания связи many-to-many между двумя моделями, вы должны сначала определить поле ManyToManyField в одной из моделей, указав в качестве аргумента модель, с которой вы хотите установить связь.
from django.db import models

class Author(models.Model):
name = models.CharField(max_length=100)

class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)


В этом примере у модели Book есть поле authors, которое является связью many to many с моделью Author. Теперь каждая книга может иметь несколько авторов, и каждый автор может быть связан с несколькими книгами.

Вы можете работать со связью many to many так же, как с другими полями модели. Например, вы можете добавлять, удалять и получать связанные объекты, а также выполнять запросы к ним.
# Создание книги и добавление авторов
book = Book.objects.create(title='Book Title')
author1 = Author.objects.create(name='Author 1')
author2 = Author.objects.create(name='Author 2')
book.authors.add(author1, author2)

# Получение всех книг, написанных определенным автором
author = Author.objects.get(name='Author 1')
books = author.book_set.all()

# Получение всех авторов книги
book = Book.objects.get(title='Book Title')
authors = book.authors.all()


Связь many to many автоматически создает промежуточную таблицу для хранения связей между объектами двух моделей. Эта таблица создается скрытно и обрабатывается фреймворком Django, что делает работу с такими связями удобной и прозрачной для разработчика.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Для чего подходят асинхронные операции ?
Спросят с вероятностью 7%

Асинхронные операции подходят для решения задач, которые включают в себя блокирующие операции ввода-вывода (I/O-bound operations), то есть операции, которые требуют времени на ожидание ответа от внешних источников данных, таких как сетевые запросы, операции с базой данных, чтение и запись файлов и т. д.

Преимущества использования асинхронных операций:

Улучшение производительности: Позволяют эффективно использовать ресурсы процессора, так как они не блокируют основной поток выполнения в ожидании завершения операции I/O. Вместо этого, когда операция завершается, управление передается другим операциям, что позволяет увеличить производительность приложения.

Масштабируемость: Обеспечивают лучшую масштабируемость приложений, особенно в случае большого количества одновременных запросов. При использовании сетевых приложений, например, они позволяют обрабатывать тысячи или даже миллионы одновременных подключений.

Улучшение отзывчивости приложения: Использование позволяет сделать ваше приложение более отзывчивым, так как оно не будет блокироваться при выполнении долгих операций I/O. Пользователи будут получать быстрый ответ от приложения даже в случае выполнения долгих операций.

Экономия ресурсов: Позволяют более эффективно использовать ресурсы сервера, так как они позволяют обрабатывать большое количество запросов с использованием меньшего количества потоков или процессов.

Примеры задач, для которых подходят асинхронные операции, включают в себя веб-серверы, API, обработку данных в реальном времени, микросервисы, чаты и мессенджеры, а также любые приложения, работающие с большим объемом асинхронных запросов и операций I/O.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Что такое миграция ?
Спросят с вероятностью 7%

Миграция (migration) - это процесс автоматического изменения структуры базы данных на основе изменений в определении моделей. Когда вы вносите изменения в структуру моделей, например, добавляете новое поле, удаляете существующее поле или изменяете тип данных поля, вы создаете миграцию.

Миграции - это набор инструкций, которые описывают, как нужно изменить структуру базы данных, чтобы она соответствовала новому определению моделей. Эти процессы создаются с помощью инструмента командной строки manage.py и хранятся в директории migrations внутри каждого приложения.

Процесс работы с миграциями обычно выглядит следующим образом:

1️⃣ Вы вносите изменения в определения моделей(например, добавляете новое поле или изменяете существующее).

2️⃣ Создаете миграцию с помощью команды makemigrations. Django анализирует изменения в моделях и создает новую миграцию в соответствующей директории migrations.

3️⃣ Применяете миграцию к базе данных с помощью команды migrate. Django выполнит все новые миграции и применит изменения к базе данных.

Примеры типовых операций:

- makemigrations: Создание новой миграции на основе изменений в моделях.
- migrate: Применение всех непримененных миграций и обновление структуры базы данных.
- showmigrations: Показывает статус всех миграций в приложении.
- sqlmigrate: Показывает SQL-код для определенной миграции.
- squashmigrations: Объединение нескольких миграций в одну.

Миграции позволяют управлять структурой базы данных в Django, сохраняя целостность и консистентность данных при изменениях в определениях моделей.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
В чем преимущество ORM перед созданием запросов вручную ?
Спросят с вероятностью 7%

ORM (Object-Relational Mapping) предоставляет абстракцию над базой данных, позволяя вам работать с данными, как с объектами, вместо того чтобы писать SQL-запросы вручную. Вот несколько преимуществ ORM перед созданием запросов вручную:

1️⃣ Более высокий уровень абстракции: Он позволяет вам думать о данных в терминах объектов и их связей, что делает код более понятным и легким для сопровождения. Вам не нужно думать о том, как представить данные в базе данных, так как ORM делает это за вас.

2️⃣ Безопасность и защита от SQL-инъекций: При его использовании данные параметризуются автоматически, что защищает от SQL-инъекций. ORM обрабатывает множество проблем безопасности данных, таких как экранирование специальных символов и форматирование значений.

3️⃣ Переносимость: При его использовании код становится более переносимым между различными СУБД, так как ORM обрабатывает различия в синтаксисе SQL и внутреннем устройстве СУБД.

4️⃣ Удобство в использовании: Он предоставляет более простой и выразительный способ работы с данными. Он облегчает создание, изменение и удаление записей в базе данных, а также обеспечивает возможность работы с данными на уровне объектов Python.

5️⃣ Меньше повторяющегося кода: Он автоматически генерирует большую часть SQL-кода, что сокращает объем повторяющегося кода и упрощает разработку.

6️⃣ Интеграция с языком программирования: Он позволяет использовать язык программирования для создания и выполнения запросов к базе данных, что делает код более читаемым и понятным.

Хотя ORM имеет множество преимуществ, иногда в некоторых ситуациях создание запросов вручную может быть более эффективным. Это обычно происходит в случае выполнения сложных SQL-операций или когда необходимо получить максимальную производительность. Однако в большинстве случаев ORM обеспечивает более удобный и безопасный способ работы с базой данных.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Какая сложность основных операций в коллекциях ?
Спросят с вероятностью 7%

Временная сложность (в худшем случае) основных операций в коллекциях зависит от типа коллекции и реализации конкретной структуры данных. Вот общие характеристики сложности основных операций для некоторых типов коллекций:

1️⃣ Список (List):
- Доступ к элементу по индексу (indexing): O(1)
- Вставка в конец (append): O(1)
- Вставка в начало (insert): O(n)
- Удаление элемента по индексу (pop): O(n)
- Удаление элемента по значению (remove): O(n)
- Поиск элемента (in): O(n)

2️⃣ Словарь (Dictionary):
- Доступ к элементу по ключу (get): O(1)
- Вставка элемента (set): O(1)
- Удаление элемента по ключу (del): O(1)
- Проверка наличия ключа (in): O(1)
- Перебор всех элементов: O(n)

3️⃣ Множество (Set):
- Добавление элемента (add): O(1)
- Удаление элемента (remove): O(1)
- Проверка наличия элемента (in): O(1)
- Перебор всех элементов: O(n)

4️⃣ Кортеж (Tuple):
- Доступ к элементу по индексу (indexing): O(1)
- Перебор всех элементов: O(n)

Важно отметить, что эти сложности могут варьироваться в зависимости от реализации конкретной структуры данных и конкретных операций. Например, вставка в середину списка может иметь сложность O(n), если при этом требуется сдвигать все элементы вправо, чтобы освободить место для нового элемента. Поэтому при выборе структуры данных для конкретной задачи важно учитывать типичные операции, которые будут выполняться с данными, и их ожидаемую сложность.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Какие очевидные недостатки у рекурсии ?
Спросят с вероятностью 7%

Хотя рекурсия является мощным инструментом и может использоваться для решения множества задач, у нее также есть несколько очевидных недостатков:

1️⃣ Потребление памяти: Каждый вызов функции создает новый фрейм стека, который содержит локальные переменные, аргументы и возвратный адрес. При глубокой рекурсии стек может быстро заполниться, что может привести к его переполнению (stack overflow).

2️⃣ Сложность отладки: Рекурсивные функции могут быть сложными для отладки из-за их неявной структуры. При отладке программы может быть трудно отследить порядок вызовов функций и значения аргументов.

3️⃣ Сложность понимания: Может быть трудно понять рекурсивные функции из-за их структуры и необходимости думать о базовом случае и шаге.

4️⃣ Производительность: В некоторых случаях рекурсивные решения могут быть менее эффективными по сравнению с итеративными. Это связано с накладными расходами на вызов функции и управление стеком.

5️⃣ Возможность зацикливания: Некорректная реализация рекурсивной функции может привести к бесконечной рекурсии, если базовый случай не достигнут или условие выхода из нее неверно определено.

Хотя рекурсия может быть полезным инструментом в решении некоторых задач, ее следует использовать осторожно, учитывая вышеуказанные недостатки. В некоторых случаях лучше предпочесть итеративные решения или использовать рекурсию в сочетании с другими методами, чтобы избежать перечисленных проблем.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Какие преимущества рекурсивного подхода ?
Спросят с вероятностью 7%

Рекурсивный подход имеет несколько преимуществ, которые делают его мощным и удобным инструментом в решении некоторых задач:

1️⃣ Ясность и читаемость кода: Рекурсивные функции могут быть более лаконичными и выразительными, чем их итеративные аналоги, что делает код более понятным и читаемым для других разработчиков.

2️⃣ Простота и понятность решения: В некоторых случаях этот подход может быть более естественным и интуитивно понятным для решения задачи, особенно если задача сама по себе рекурсивна.

3️⃣ Меньше повторяющегося кода: Такой подход позволяет избежать дублирования кода путем вызова функции из самой себя с различными аргументами.

4️⃣ Решение сложных задач: Данный подход может быть очень мощным для решения задач, связанных с древовидными или рекурсивными структурами данных, такими как бинарные деревья или графы.

5️⃣ Использование стека вызовов: Рекурсивные функции используют стек вызовов для хранения промежуточных результатов, что может быть полезным для решения некоторых задач и упрощения кода.

6️⃣ Элегантное решение задач: В некоторых случаях рекурсивное решение задачи может быть более элегантным и эффективным по сравнению с итеративным.

Хотя рекурсивный подход имеет свои преимущества, важно помнить о его ограничениях и возможных недостатках, таких как потребление памяти и производительность, и использовать его там, где он подходит и обеспечивает преимущества по сравнению с другими методами.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Что возвращает метод init ?
Спросят с вероятностью 7%

Метод init() не возвращает явным образом никакого значения. Он используется для инициализации нового объекта после его создания. Когда вы создаете новый экземпляр класса, вызывается данный метод, который может выполнять какую-либо начальную настройку объекта, устанавливать его атрибуты и выполнять другие необходимые операции.

class MyClass:
def __init__(self, x, y):
self.x = x
self.y = y

obj = MyClass(10, 20)

В этом примере, при создании нового объекта obj класса MyClass с аргументами 10 и 20, вызывается данный метод, который устанавливает атрибуты x и y нового объекта.

Хотя метод init() не возвращает никакого значения, вы можете явно указать его вернуть что-то, если это необходимо, но это не типичное использование этого метода и может привести к путанице при чтении кода. Обычно init() используется только для инициализации объекта, а не для возврата значений.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Что делает метод new ?
Спросят с вероятностью 7%

Метод new() является статическим, и используется для создания нового экземпляра класса. Он вызывается перед методом init() при создании нового объекта.

В отличие от метода init(), который инициализирует уже созданный объект, данный метод создает новый объект. Обычно вы переопределяете этот метод только в специальных случаях, когда вам нужно настроить способ создания объекта или выполнить какую-то предварительную обработку до его инициализации.

Основное использование метода включает в себя:

1️⃣ Переопределение метода new() для настройки поведения создания объекта, например, для создания объекта определенного подкласса в зависимости от некоторого условия.
2️⃣ Вызов данного метода в метаклассах для создания нового экземпляра класса при определении класса.
class MyClass:
def new(cls, *args, **kwargs):
# Создание нового экземпляра класса
instance = super().new(cls)
# Некоторая предварительная обработка перед инициализацией
print("Создан новый объект")
return instance

def init(self, x):
self.x = x

obj = MyClass(10)

В этом примере метод new() создает новый объект класса MyClass, а затем вызывается метод init() для его инициализации.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Что такое классы ?
Спросят с вероятностью 7%

Классы - это шаблоны или чертежи, которые определяют атрибуты и методы объектов. Они используются для создания новых объектов, которые могут содержать данные (атрибуты) и функции (методы) для работы с этими данными. Класс является основой объектно-ориентированного программирования (ООП).

Основные компоненты:

1️⃣ Атрибуты: Переменные, хранящие данные, связанные с классом. Атрибуты могут быть публичными (доступными извне класса), защищенными (доступными только внутри класса и его подклассов) или приватными (доступными только внутри класса).

2️⃣ Методы: Функции, определенные внутри класса и используемые для работы с атрибутами объектов этого класса. Методы могут изменять состояние объекта или возвращать какие-то значения.

3️⃣ Инициализатор: Специальный метод init(), который вызывается при создании нового объекта класса и используется для инициализации его атрибутов.

4️⃣ Конструктор: Специальный метод new(), который вызывается перед init() и используется для создания нового экземпляра класса.

5️⃣ Деструктор: Специальный метод del(), который вызывается при удалении объекта из памяти и используется для освобождения ресурсов или выполнения других операций при завершении работы объекта.
class MyClass:
def init(self, x):
self.x = x

def my_method(self):
return self.x * 2

# Создание объекта класса MyClass
obj = MyClass(10)
print(obj.my_method()) # Выводит: 20

В этом примере определен класс MyClass, у которого есть атрибут x, инициализируемый при создании объекта, и метод my_method(), который возвращает удвоенное значение атрибута x объекта. Создается объект класса MyClass с атрибутом x, равным 10, и вызывается метод my_method() для этого объекта.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Какие коллекции из модуля collections существуют ?
Спросят с вероятность 7%

Модуль collections предоставляет различные специализированные коллекции, которые расширяют функциональность встроенных, таких как списки, словари, множества и др. Некоторые из наиболее часто используемых коллекций из этого модуля:

1️⃣ namedtuple: Создает именованные кортежи, которые представляют собой легковесную альтернативу определению собственных классов для представления данных.

2️⃣ deque: Это двусторонняя очередь (double-ended queue), которая предоставляет эффективные операции добавления и удаления элементов как в начале, так и в конце коллекции.

3️⃣ Counter: Это подсчетчик элементов, который подсчитывает количество вхождений каждого элемента в последовательность и предоставляет удобный доступ к этим значениям.

4️⃣ OrderedDict: Это словарь, который помнит порядок вставки элементов, что полезно при итерации и выводе результатов в определенном порядке.

5️⃣ defaultdict: Это словарь, который автоматически создает значения по умолчанию для отсутствующих ключей при первом обращении к ним.

6️⃣ ChainMap: Представляет собой объединение нескольких словарей в один и обеспечивает удобный способ просмотра и обновления значений в этих словарях.

7️⃣ UserDict: Это базовый класс, который позволяет создавать пользовательские классы словарей, наследуясь от него и переопределяя методы словаря.

8️⃣ UserList: Аналогично UserDict, но для списков.

9️⃣ UserString: Аналогично UserDict, но для строк.

Эти коллекции предоставляют дополнительные возможности и улучшают функциональность базовых коллекций, делая их более удобными и эффективными для использования в различных сценариях.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Что можно сказать о бинарном дереве ?
Спросят с вероятностью 7%

Бинарное дерево - это структура данных, состоящая из узлов, каждый из которых имеет не более двух потомков: левого и правого. Каждый узел содержит некоторое значение (ключ) и ссылки на его левого и правого потомков (или на None, если потомок отсутствует).

Основные характеристики бинарного дерева:

1️⃣ Корень (Root): Это верхний узел дерева, от которого начинается структура.

2️⃣ Уровень (Level): Каждый узел дерева расположен на определенном уровне. Уровень корня равен 0, уровень его детей равен 1 и так далее.

3️⃣ Листья (Leaves): Это узлы дерева, у которых отсутствуют потомки. То есть они конечные в дереве.

4️⃣ Высота (Height): Это количество уровней в дереве. Максимальная высота бинарного дерева равна максимальному количеству уровней от корня до самого далекого листа.

5️⃣ Балансировка (Balanced): Бинарное дерево называется сбалансированным, если разница в высоте между левым и правым поддеревьями на каждом узле не превышает 1. Такие деревья обеспечивают эффективный поиск, вставку и удаление элементов.

6️⃣ Порядок (Traversal): Существуют различные способы обхода бинарного дерева для выполнения операций с его элементами. Эти методы включают в себя префиксный (pre-order), инфиксный (in-order) и постфиксный (post-order) обходы.

7️⃣ Операции: Бинарное дерево обычно поддерживает операции вставки, удаления и поиска элементов. Эти операции выполняются за время O(log n) в сбалансированных деревьях и до O(n) в худшем случае в несбалансированных.

Бинарные деревья широко применяются в компьютерных науках для построения эффективных структур данных, таких как двоичные поисковые деревья, кучи и многие другие. Они позволяют эффективно хранить, обрабатывать и извлекать данные, делая их незаменимым инструментом в различных алгоритмах и приложениях.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Принципы программирования KISS ?
Спросят с вероятностью 7%

KISS (Keep It Simple, Stupid) - это принцип проектирования ПО, который призывает к тому, чтобы решения были максимально простыми и непритязательными. Имеет следующие ключевые аспекты:

1️⃣ Простота и ясность: ПО должно быть простым и понятным для понимания, как для его создателей, так и для пользователей. Простота снижает сложность, упрощает разработку и обслуживание кода.

2️⃣ Отказ от избыточности: Избегайте излишних деталей и сложных конструкций в коде. Пишите только тот код, который необходим для решения задачи.

3️⃣ Работоспособность и надежность: Простота не должна жертвовать работоспособностью и надежностью программы. ПО должно продолжать работать правильно и стабильно при любых условиях.

4️⃣ Легкость сопровождения и расширения: ПО должно быть легко поддерживаемым и расширяемым. Простой код легче изменить, доработать и адаптировать под новые требования.

Принцип KISS подчеркивает важность обеспечения минимального количества сложности в ПО, что способствует повышению его читаемости, надежности и производительности. Он учитывает тот факт, что чем проще решение, тем менее вероятно наличие ошибок и проблем в будущем.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Какие есть четыре уровня изоляции транзакций ?
Спросят с вероятностью 7%

В стандарте ANSI/ISO SQL определены четыре уровня изоляции транзакций:

1️⃣ READ UNCOMMITTED (Неподтвержденное чтение):
- Это самый низкий уровень изоляции.
- Позволяет одной транзакции видеть изменения, внесенные другой, даже если эти изменения еще не зафиксированы (т.е., транзакция еще не завершена).
- Возможно возникновение проблем с неподтвержденным чтением и потерянными обновлениями.

2️⃣ READ COMMITTED (Подтвержденное чтение):
- Этот уровень гарантирует, что транзакция увидит только изменения, которые были подтверждены другими.
- Избегает проблем с неподтвержденным чтением, но может возникнуть проблема с повторяемым чтением.

3️⃣ REPEATABLE READ (Повторяемое чтение):
- Гарантирует, что каждый раз, когда транзакция читает данные, она видит те же самые данные, что и в начале, даже если другая вносит изменения в эти данные.
- Избегает проблемы с повторяемым чтением, но может привести к проблемам с фантомными записями (phantom reads).

4️⃣ SERIALIZABLE (Сериализуемость):
- Это самый высокий уровень изоляции.
- Гарантирует, что все операции чтения и записи будут видеть состояние данных, как если бы они выполнялись последовательно (одна за другой), даже если фактически они выполняются параллельно.
- Избегает проблем с повторяемым чтением и фантомными записями, но может привести к увеличению блокировок и ухудшению производительности.

Выбор уровня изоляции зависит от конкретных требований вашего приложения к согласованности данных и производительности.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Какие минусы есть у индекса ?
Спросят с вероятностью 7%

Индексы в базах данных - это мощный инструмент для оптимизации запросов и ускорения доступа к данным, но они также имеют некоторые минусы:

1️⃣ Затраты на хранение: Они занимают дополнительное место на диске для хранения дополнительной структуры данных. Это может быть значительным фактором для больших таблиц с множеством индексов.

2️⃣ Затраты на обновление: При вставке, обновлении или удалении записей из таблицы они также должны быть обновлены, чтобы отразить изменения. Это может привести к дополнительным затратам на обслуживание индексов и замедлить операции записи.

3️⃣ Ухудшение производительности при обновлении: Их обновление может потребовать блокировки и увеличить время выполнения операций обновления, особенно для таблиц с большим количеством индексов.

4️⃣ Выбор неоптимальных индексов: Неправильно выбранные или ненужные индексы могут привести к избыточному использованию ресурсов и ухудшению производительности запросов.

5️⃣ Фрагментация индексов: Постоянные операции вставки, обновления и удаления могут привести к их фрагментации, что может уменьшить их эффективность.

6️⃣ Необходимость перестройки: Иногда они требуют перестройки для оптимизации их производительности, особенно если таблица значительно изменилась или индекс стал фрагментированным.

Несмотря на эти минусы, правильно спроектированные и использованные индексы могут значительно улучшить производительность запросов к базе данных. Поэтому важно тщательно оценивать их необходимость и выбирать наиболее подходящие для конкретных запросов и таблиц.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 1096 вопроса на Python разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых