1) Can you walk us through your background and how it led you to this role?
2) What motivates you to join our company?
3) How do you handle a situation where you disagree with your manager?
4) Describe a time you went above and beyond in your role.
5). How do you manage stress and tight deadlines?
6) What are your strengths and areas for improvement?
7) How do you stay updated with the latest technologies and industry trends?
1. How does Python handle memory management and garbage collection?
Answer: Python uses reference counting to track object references and a cyclic garbage collector to handle circular references. When an object’s reference count drops to zero, it’s deallocated. The gc module detects cycles using a mark-and-sweep algorithm.
Example:
import gc
class Node:
def __init__(self): self.next = None
node1, node2 = Node(), Node()
node1.next, node2.next = node2, node1 # Circular reference
del node1, node2
print(gc.collect()) # Forces collection, outputs number of objects collected
2. What is the difference between a list, tuple, set, and dictionary in Python?
Answer:
- List: Ordered, mutable, allows duplicates ([1, 2, 3]).
- Tuple: Ordered, immutable, allows duplicates ((1, 2, 3)).
- Set: Unordered, mutable, no duplicates ({1, 2, 3}).
- Dictionary: Unordered (ordered in Python 3.7+), mutable, key-value pairs ({'a': 1, 'b': 2}).
Example:
lst = [1, 1, 2]; lst.append(3) # Mutable
tpl = (1, 1, 2) # Immutable
st = {1, 1, 2} # {1, 2}, no duplicates
dct = {'a': 1, 'b': 2} # Key-value
print(lst, tpl, st, dct)
3. **What are *args and kwargs, and how are they used?
Answer: *args collects positional arguments into a tuple, and **kwargs collects keyword arguments into a dictionary. They allow functions to accept variable numbers of arguments.
Example:
def func(*args, **kwargs):
print("Positional:", args)
print("Keyword:", kwargs)
func(1, 2, a=3, b=4) # Positional: (1, 2), Keyword: {'a': 3, 'b': 4}
4. Explain Python’s Global Interpreter Lock (GIL) and its impact on multi-threading.
Answer: The GIL is a mutex that protects access to Python objects, preventing multiple native threads from executing Python bytecodes simultaneously. It simplifies memory management but limits true parallelism in CPython, making multi-threading better for I/O-bound tasks than CPU-bound tasks.
Example:
import threading
def count(n):
while n > 0: n -= 1
threads = [threading.Thread(target=count, args=(1000000,)) for _ in range(2)]
for t in threads: t.start()
for t in threads: t.join() # GIL limits CPU-bound parallelism
5. What is a decorator, and how do you create one?
Answer: A decorator is a function that wraps another function to extend its behavior without modifying its code. It’s commonly used for logging, authentication, or timing.
Example:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Before function")
result = func(*args, **kwargs)
print("After function")
return result
return wrapper
@my_decorator
def say_hello(name):
return f"Hello, {name}!"
print(say_hello("Alice")) # Outputs: Before function, Hello, Alice!, After function
6. What is the difference between __str__ and __repr__ methods?
Answer: __str__ provides a user-friendly string representation of an object, used by print(). __repr__ provides a detailed, unambiguous representation, often for debugging, used by repr().
Example:
class Person:
def __init__(self, name): self.name = name
def __str__(self): return f"Person: {self.name}"
def __repr__(self): return f"Person(name='{self.name}')"
p = Person("Alice")
print(p) # Person: Alice
print(repr(p)) # Person(name='Alice')
7. How does Python’s list comprehension work, and when should you use it?
Answer: List comprehension provides a concise way to create lists using a single line of code. It’s best for simple transformations or filtering but can reduce readability for complex logic.
Example:
# Create a list of squares for even numbers
nums = [1, 2, 3, 4]
squares = [x**2 for x in nums if x % 2 == 0] # [4, 16]
print(squares)
8. What are generators, and how do they differ from lists?
Answer: Generators are iterators that yield values one at a time, saving memory compared to lists, which store all values in memory. They’re created using yield or generator expressions.
Example:
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
gen = fibonacci(5) # Generator object
print(list(gen)) # [0, 1, 1, 2, 3]
9. How would you handle exceptions in Python, and what is the purpose of else and finally?
Answer: Exceptions are handled using try, except, else, and finally. try contains code that might raise an exception, except handles specific exceptions, else runs if no exception occurs, and finally runs regardless of exceptions.
Example:
try:
result = 10 / int(input("Enter a number: "))
except ZeroDivisionError:
print("Cannot divide by zero!")
except ValueError:
print("Invalid input!")
else:
print("Result:", result)
finally:
print("Execution complete.")
10. What is the difference between deepcopy and shallowcopy in Python?
Answer: A shallow copy (copy.copy) creates a new object but references nested objects. A deep copy (copy.deepcopy) creates a fully independent copy, including nested objects.
Example:
import copy
lst = [[1, 2], 3]
shallow = copy.copy(lst)
deep = copy.deepcopy(lst)
shallow[0][0] = 9
print(lst) # [[9, 2], 3] (shallow copy affects nested list)
print(deep) # [[1, 2], 3] (deep copy unaffected)
Django Interview Question:
1. How do you optimize Django querysets to improve performance in a production application?
Answer: Optimize querysets using:
- select_related(): For ForeignKey relationships to reduce database queries via JOINs.
- prefetch_related(): For ManyToMany or reverse ForeignKey relationships to batch queries.
- values() or only(): To fetch only required fields.
- Database indexes: Add indexes in model Meta for frequently queried fields.
- Caching: Use Django’s caching framework for frequently accessed data.
Example:
# models.py
class Order(models.Model):
customer = models.ForeignKey('Customer', on_delete=models.CASCADE)
product = models.CharField(max_length=100)
class Meta:
indexes = [models.Index(fields=['customer'])]
# views.py
def order_list(request):
# Optimized: Fetch customer data in one query
orders = Order.objects.select_related('customer').all()
return render(request, 'orders.html', {'orders': orders})
2. How do you implement custom authentication in Django?
Answer: Use Django’s authentication system by creating a custom user model (extending AbstractBaseUser or AbstractUser) or a custom authentication backend. A backend requires authenticate and get_user methods.
Example:
# backends.py
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth import get_user_model
class EmailBackend(BaseBackend):
def authenticate(self, request, username=None, password=None):
User = get_user_model()
try:
user = User.objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
User = get_user_model()
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
# settings.py
AUTHENTICATION_BACKENDS = ['myapp.backends.EmailBackend']
3. What are Django signals, and how have you used them in a project?
Answer: Signals allow decoupled applications to receive notifications when specific events occur (e.g., post_save, pre_delete). They’re useful for tasks like logging, updating related models, or sending notifications.
Example:
# signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from myapp.models import Order
@receiver(post_save, sender=Order)
def send_order_confirmation(sender, instance, created, **kwargs):
if created:
print(f"Order {instance.id} created, sending confirmation email.")
4. How do you handle file uploads in Django securely?
Answer: Use Django’s FileField or ImageField, validate file types and sizes, store files in a secure location (e.g., MEDIA_ROOT), and avoid executing uploaded content. Use libraries like Pillow for image validation.
Example:
# models.py
from django.db import models
class Document(models.Model):
file = models.FileField(upload_to='documents/')
# forms.py
from django import forms
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ['file']
def clean_file(self):
file = self.cleaned_data['file']
if file.size > 5 * 1024 * 1024: # 5MB limit
raise forms.ValidationError("File too large.")
return file
# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = 'media/'
5. How do you implement pagination in Django, and why is it important?
Answer: Pagination improves performance by limiting the number of records displayed per page. Use Django’s Paginator class or generic views like ListView with paginate_by.
Example:
# views.py
from django.core.paginator import Paginator
from django.shortcuts import render
from myapp.models import Product
def product_list(request):
products = Product.objects.all()
paginator = Paginator(products, 10) # 10 items per page
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'products.html', {'page_obj': page_obj})
# products.html
{% for product in page_obj %}
<p>{{ product.name }}</p>
{% endfor %}
<div>
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">Next</a>
{% endif %}
</div>
6. How do you secure a Django application against common vulnerabilities like CSRF and SQL injection?
Answer: Django provides built-in protections:
- CSRF: Use {% csrf_token %} in forms and enable CsrfViewMiddleware.
- SQL Injection: Use Django’s ORM to avoid raw SQL queries.
- XSS: Escape template output (default in Django) and avoid |safe unless necessary.
- Other: Use HTTPS, secure password hashing, and limit user input.
Example:
<form method="post">
{% csrf_token %}
<input type="text" name="username">
<button type="submit">Submit</button>
</form>
7. What is the Django REST Framework, and how do you create a simple API endpoint?
Answer: DRF is a toolkit for building RESTful APIs. It provides serializers, views, and authentication. Create an API using models, serializers, and views (e.g., APIView or generics).
Example:
# serializers.py
from rest_framework import serializers
from myapp.models import Task
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = ['id', 'title']
# views.py
from rest_framework import generics
from myapp.models import Task
from .serializers import TaskSerializer
class TaskList(generics.ListCreateAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
# urls.py
from django.urls import path
from .views import TaskList
urlpatterns = [path('api/tasks/', TaskList.as_view())]
8. How do you handle database transactions in Django?
Answer: Django’s ORM wraps database operations in transactions by default. Use @transaction.atomic for explicit control, ensuring operations either complete fully or roll back on failure.
Example:
from django.db import transaction
from myapp.models import Account
@transaction.atomic
def transfer_money(from_account_id, to_account_id, amount):
from_account = Account.objects.get(id=from_account_id)
to_account = Account.objects.get(id=to_account_id)
from_account.balance -= amount
to_account.balance += amount
from_account.save()
to_account.save()
9. How do you debug a slow Django application?
some text** Answer: To debug a slow Django application:
- Use Django Debug Toolbar to profile queries.
- Check for N+1 query issues with select_related or prefetch_related.
- Enable database query logging to identify slow queries.
- Use caching (e.g., Redis, Memcached) for repetitive queries.
- Optimize templates and static files.
Example:
# settings.py
LOGGING = {
'version': 1,
'handlers': {'console': {'class': 'logging.StreamHandler'}},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
}
}
}
# Run with DEBUG=True to see SQL queries in console
2. How do you create a serializer in DRF, and what is its purpose?
Answer: A serializer in DRF converts complex data (e.g., model instances) into JSON or other formats and vice versa. It handles data validation and transformation. Use Serializer for custom logic or ModelSerializer for model-based serialization.
Example:
from rest_framework import serializers
from myapp.models import Task
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = ['id', 'title', 'created_at']
read_only_fields = ['created_at']
def validate_title(self, value):
if len(value) < 3:
raise serializers.ValidationError("Title must be at least 3 characters.")
return value
type of serializer and difference between them:
Types of Serializers in DRF
- Serializer (Base Serializer)
- ModelSerializer
- HyperlinkedModelSerializer
- ListSerializer
- BaseSerializer (for advanced customization)
Differences Between Serializers
Serializer Type | Purpose | Key Features | When to Use |
---|---|---|---|
Serializer | Custom serialization for non-model or complex data. | Manual field definitions, full control over serialization/deserialization logic. | When dealing with non-model data or needing custom serialization logic. |
ModelSerializer | Automatic serialization for Django models. | Auto-generates fields from model, supports model validation, and CRUD operations. | When working directly with Django models and wanting minimal configuration. |
HyperlinkedModelSerializer | Like ModelSerializer but uses hyperlinks for relationships. | Includes hyperlinked fields for relationships (e.g., URLs to related objects). | When APIs need navigable links for related resources (e.g., RESTful design). |
ListSerializer | Handles serialization of lists of objects. | Used internally by many=True or for bulk operations. | When serializing multiple objects or implementing bulk create/update. |
BaseSerializer | Base class for fully custom serialization logic. | Minimal functionality, requires manual implementation of serialization methods. | For highly customized serialization not tied to models or standard JSON output. |
How do you use DRF’s ViewSets with routers to simplify URL routing?
Answer: ViewSets combine related views (e.g., list, create, retrieve) into a single class. DRF’s DefaultRouter automatically generates URL patterns for ViewSets.
Example:
# views.py
from rest_framework import viewsets
from myapp.models import Task
from .serializers import TaskSerializer
class TaskViewSet(viewsets.ModelViewSet):
queryset = Task.objects.all()
serializer_class = TaskSerializer
# urls.py
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'tasks', TaskViewSet)
urlpatterns = router.urls
# Generates: /api/tasks/, /api/tasks/<pk>/
How do you handle relationships in DRF serializers?
Answer: Relationships can be handled using PrimaryKeyRelatedField (IDs), StringRelatedField (string representation), Nested Serializers (full objects), or HyperlinkedRelatedField (URLs). Optimize with select_related or prefetch_related.
Example:
pythonfrom rest_framework import serializers
from myapp.models import Author, Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', 'title']
class AuthorSerializer(serializers.ModelSerializer):
books = BookSerializer(many=True, read_only=True) # Nested
class Meta:
model = Author
fields = ['id', 'name', 'books']
# Optimize queries in view
class AuthorList(APIView):
def get(self, request):
authors = Author.objects.prefetch_related('books')
serializer = AuthorSerializer(authors, many=True)
return Response(serializer.data)
Answer: Relationships can be handled using PrimaryKeyRelatedField (IDs), StringRelatedField (string representation), Nested Serializers (full objects), or HyperlinkedRelatedField (URLs). Optimize with select_related or prefetch_related.
Example:
pythonfrom rest_framework import serializers
from myapp.models import Author, Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', 'title']
class AuthorSerializer(serializers.ModelSerializer):
books = BookSerializer(many=True, read_only=True) # Nested
class Meta:
model = Author
fields = ['id', 'name', 'books']
# Optimize queries in view
class AuthorList(APIView):
def get(self, request):
authors = Author.objects.prefetch_related('books')
serializer = AuthorSerializer(authors, many=True)
return Response(serializer.data)
POST Answer of Questions and ASK to Doubt