Barcha savollar

Python bo'yicha eng ko'p so'raladigan 20 ta intervyu savoli va javoblari

Python intervyusiga tayyorlanyapsizmi? Mantiq, syntax va ilg'or ko'nikmalaringizni namoyish etishga yordam beradigan aniq javoblar, kod misollari va maslahatlar bilan 20 ta asosiy savolni ko'rib chiqing.

Muallif: Ekene Eze

Python intervyulari faqat syntax'ni tekshirmaydi. Ular qanday fikrlashingizni tekshiradi.

Python intervyusi tilning imkoniyatlarini shunchaki birma-bir ko'rib chiqishdan iborat bo'ladi, deb kutishingiz mumkin. Ammo ko'pincha intervyu oluvchilarni siz qancha method yodlab olganingiz qiziqtirmaydi. Ularni Python'ni vosita sifatida ishlatib, muammolarni qanday hal qilishingiz qiziqtiradi.

Eng qiyin savollar ba'zan eng oddiylari bo'ladi. Sizdan list'lar, dictionary'lar yoki loop'lardan foydalanish so'raladi, ammo aslida ular mantiqingiz qanchalik aniq ekanini, kodingiz qanchalik toza ko'rinishini va Python'ning kuchli tomonlaridan qanchalik yaxshi foydalanishingizni tekshiradi.

Ushbu qo'llanmada siz:

  • 20 ta Python intervyu savoli va javoblari bilan mashq qilasiz

  • Kod misollarini ko'rib chiqasiz va keng tarqalgan xatolardan saboq olasiz

  • Asosiy syntax hamda decorator'lar, memory management va Pandas kabi ilg'or mavzularni o'rganasiz

  • Flashcard'lar va o'z-o'zini tekshirish mashqlari yordamida bilimingizni mustahkamlaysiz

  • O'rganishni davom ettirish va Python ko'nikmalaringizni oshirish uchun Python roadmap'iga amal qilasiz

Endi bu qo'llanmada nimalar borligini bilasiz, demak, boshlash vaqti keldi. Keling, Python intervyusiga qanday tayyorlanishni bosqichma-bosqich ko'rib chiqamiz.

Python intervyusiga tayyorgarlik

Python intervyusida muvaffaqiyat qozonish uchun quyidagi maslahatlarni yodda tuting:

  • Asoslarni puxta o'zlashtiring: Data type'lar, funksiyalar, list comprehension'lar va OOP'ni mustahkam bilib oling. Scope, mutability va memory management kabi chalkash mavzularga alohida e'tibor qarating.

  • Kasbiy yo'nalishingizga qarab tayyorlaning: Agar data yo'nalishidagi lavozimga intervyu topshirayotgan bo'lsangiz, NumPy, Pandas va data visualization'ga e'tibor bering. Veb-dasturlash uchun Flask, Django va REST API'larni biling. Backend yoki tizim darajasidagi ishlar uchun concurrency, multithreading va performance tuning'ni o'rganing.

  • Maqsadli mashq qiling: LeetCode yoki HackerRank kabi platformalar algoritmlar uchun juda yaxshi, ammo toza, production-ready kod yoza olishingizni isbotlaydigan kichik loyihalar ham yarating.

  • Faqat kodingizni emas, fikrlash jarayoningizni ham ko'rsating: Intervyu oluvchilar qanday fikrlashingizni ko'rishni xohlaydi. “Mukammal” yechimga intilish o'rniga mantiqingizni bosqichma-bosqich tushuntiring, edge case'larni tekshiring va trade-off'larni izohlang.

  • Kompaniyaning stack'ini biling: Ular Django yoki FastAPI, Pandas yoki Spark, AWS yoki GCP'dan qaysi birini ishlatishini aniqlang. Javoblaringiz va savollaringiz ularga mos tushishi uchun tayyorgarligingizni shunga moslang.

  • Ushbu qo'llanmadan faol foydalaning: Bu qo'llanmani shunchaki ko'z yugurtirib o'tmang — kodni o'zingiz yozing, turli variantlar bilan tajriba qiling va o'zingizni sinash uchun flashcard'lardan foydalaning.

Flashcard'lar yordamida o'zingizni sinab ko'ring

Siz ushbu flashcard'lardan foydalanishingiz yoki savollarni ro'yxat ko'rinishida ko'rish uchun quyidagi savollar ro'yxati bo'limiga o'tishingiz mumkin.

Savollar ro'yxati

Agar savollarni ro'yxat ko'rinishida ko'rishni afzal ko'rsangiz, ularni quyida topishingiz mumkin.

Python asoslari va asosiy tushunchalar

Python nima va nega u high-level interpreted dasturlash tili deb ataladi?

Python high-level dasturlash tili hisoblanadi, chunki u memory management va apparat qismi bilan o'zaro ishlash kabi low-level tafsilotlarni siz uchun o'zi hal qiladi. U sizga aniq, o'qilishi oson va mashina ko'rsatmalariga qaraganda inson tiliga yaqinroq kod yozish imkonini beradi.

U interpreted til hisoblanadi, chunki Python interpreter avval hamma narsani machine code'ga kompilyatsiya qilish o'rniga kodni runtime'da satrma-satr bajaradi.

Keng tarqalgan xatolar va maslahatlar:

  • "Interpreted" degani Python'ni kompilyatsiya qilib bo'lmaydi degani, deb o'ylash. PyInstaller yoki Cython kabi vositalar Python kodini paketlashi mumkin.

  • Texnik tafsilotlarni haddan tashqari ko'p tushuntirish. Bu ko'pincha muloqot ko'nikmalarini tekshirish uchun beriladigan "qizdiruvchi" savol, shuning uchun javobingizni qisqa va aniq qiling.

Python'da mutable va immutable data type'lar nima? Misollar keltiring.

Python'da mutable data type'larni yaratilgandan keyin o'zgartirish mumkin. Ularni yangilash, ulardan element o'chirish va ularga element qo'shish mumkin. Masalan, list, dict va set.

Immutable obyektlarni yaratilgandan keyin o'zgartirib bo'lmaydi; har qanday o'zgarish yangi obyekt hosil qiladi. Masalan, str, tuple, int va float.

# Mutable examples
my_list = [1, 2, 3]
my_list.append(4) # Modifies the original list
print(my_list) # [1, 2, 3, 4] 

my_dict = {'a': 1}
my_dict['b'] = 2 # Modifies the original dictionary
print(my_dict) # {'a': 1, 'b': 2} 

# Immutable examples
my_string = "hello"
new_string = my_string.upper() # Creates a new string
print(my_string) # "hello" (unchanged)
print(new_string) # "HELLO" 

my_tuple = (1, 2, 3)
# my_tuple[0] = 4 # This would raise a TypeError

Keng tarqalgan xatolar va maslahatlar:

  • O'zgaruvchini qayta bog'lash bilan obyektni o'zgartirishni adashtirish. Masalan, x = x + [4] yangi list yaratadi va x'ni unga qayta bog'laydi, x.append(4) esa mavjud list'ning o'zini joyida o'zgartiradi.

  • Immutability nima uchun muhimligini tushunmaslik. Immutable obyektlar dictionary key'lari bo'la oladi va hashable hisoblanadi, mutable obyektlar esa bunday emas.

Global scope, local scope va nonlocal o'zgaruvchilar o'rtasida qanday farq bor?

Python scope resolution uchun LEGB qoidasiga amal qiladi: Local → Enclosing → Global → Built-in.

  • Local scope: Funksiya ichida aniqlangan o'zgaruvchilar

  • Global scope: Module darajasida aniqlangan o'zgaruvchilar

  • Nonlocal: Enclosing funksiya scope'idagi o'zgaruvchilar

global_var = "I'm global"

def outer_function():
    enclosing_var = "I'm in enclosing scope"

    def inner_function():
        local_var = "I'm local"

        # Accessing different scopes
        print(local_var)      # Local
        print(enclosing_var)  # Enclosing
        print(global_var)     # Global

        # Modifying enclosing scope
        nonlocal enclosing_var
        enclosing_var = "Modified from inner"

        # Modifying global scope
        global global_var
        global_var = "Modified globally"

    inner_function()
    print(enclosing_var)  # "Modified from inner"

outer_function()
print(global_var)  # "Modified globally"

Keng tarqalgan xatolar va maslahatlar:

  • Global o'zgaruvchilardan haddan tashqari ko'p foydalanish kodning o'qilishini yomonlashtirishi va debugging'ni qiyinlashtirishi mumkin. Intervyularda buni best practice sifatida tilga oling.

  • Tashqi scope'lardagi o'zgaruvchilarni o'zgartirmoqchi bo'lganda global yoki nonlocal keyword'laridan foydalanishni unutish — ularsiz siz yangi local o'zgaruvchilar yaratib qo'yasiz.

Python'ning built-in ma'lumotlar tuzilmalari qaysilar va ularning har biri qachon ishlatiladi?

Python'da to'rtta asosiy built-in ma'lumotlar tuzilmasi bor: list'lar, tuple'lar, dictionary'lar va set'lar. Sizga tartib, mutability, noyoblik yoki tez lookup kerakligiga qarab, ularning har biri o'z trade-off'lariga ega.

  • List'lar: Tartiblangan, mutable to'plamlar. Tartibni saqlash hamda element qo'shish/o'chirish kerak bo'lganda ishlating.
shopping_list = ['eggs', 'milk', 'bread']
shopping_list.append('cheese')
  • Tuple'lar: Tartiblangan, immutable to'plamlar. O'zgarmasligi kerak bo'lgan qat'iy ma'lumotlar uchun ishlating.
coordinates = (10.5, 20.3)
rgb_color = (255, 128, 0)
  • Dictionary'lar: Key-value juftliklari, mutable. Tez lookup'lar, mapping'lar va key mavjudligini O(1) time complexity bilan tekshirish uchun ishlating."
person = {'name': 'Alice', 'age': 30, 'city': 'New York'}
  • Set'lar: Noyob elementlarning tartiblanmagan to'plamlari, mutable. Membership testing va takrorlanuvchi elementlarni olib tashlash uchun ishlating.
unique_numbers = {1, 2, 3, 4, 5}
seen_users = set()

Keng tarqalgan xatolar va maslahatlar:

  • Noyoblik kerak bo'lsa, list'lardan ko'ra set'larni afzal ko'ring — list'da element borligini tekshirish O(n), set'dagi lookup esa O(1).

  • Python 3.7 dan oldin dictionary'lar elementlarning qo'shilish tartibini saqlashni kafolatlamagan.

  • Dictionary yoki set samaraliroq bo'ladigan holatlarda lookup uchun list'dan foydalanmang.

Shallow copy va deep copy o'rtasida qanday farq bor?

Shallow copy va deep copy o'rtasidagi farq ularning obyekt reference'lari bilan qanday ishlashida:

  • Shallow copy yangi konteyner yaratadi, ammo ichki obyektlar baribir umumiy reference'lar bo'lib qoladi.

  • Deep copy barcha ichki obyektlarni ham qo'shgan holda to'liq mustaqil nusxa yaratadi.

import copy 

original = [[1, 2], [3, 4]] 

# Assignment - same object
assigned = original 

# Shallow copy - new object, shared nested objects
shallow = copy.copy(original)
# or shallow = original.copy()
# or shallow = list(original) 

# Deep copy - completely independent
deep = copy.deepcopy(original) 

# Modify the original
original[0][0] = 99 

print("Original:", original) # [[99, 2], [3, 4]]
print("Assigned:", assigned) # [[99, 2], [3, 4]] - same object
print("Shallow:", shallow) # [[99, 2], [3, 4]] - shared nested objects
print("Deep:", deep) # [[1, 2], [3, 4]] - independent copy

Keng tarqalgan xatolar va maslahatlar:

  • Qiymat berish (=) bilan nusxa olishni adashtirish. Qiymat berish nusxa yaratmaydi, balki o'sha obyektning o'ziga yangi reference yaratadi.

  • Ichida mutable obyektlar bo'lgan tuzilmalarda shallow copy'dan foydalanib, reference'lar umumiy bo'lishini kutmaslik; bu kutilmagan o'zgarishlarga olib kelishi mumkin.

  • Unumdorlikka ta'sirini tushunmaslik. Katta va chuqur ichma-ich joylashgan tuzilmalar uchun deep copy qimmatga tushishi mumkin.

Python'da memory allocation va garbage collection qanday amalga oshiriladi?

Python xotirani avtomatik ravishda uch yo'l bilan boshqaradi:

  • Memory allocation: Python obyektlarni saqlash uchun private heap'dan foydalanadi. Python memory manager allocation va deallocation'ni avtomatik bajaradi.

  • Reference counting: Har bir obyekt unga nechta reference ko'rsatib turganini kuzatib boradi. Bu son nolga yetganda obyekt darhol deallocate qilinadi.

  • Cycle detection: Cyclic garbage collector reference counting hal qila olmaydigan circular reference'larni boshqaradi.

Odatda xotirani qo'lda boshqarishingiz shart emas, lekin buni tushunish performance optimization'da va memory leak'larni debug qilishda yordam beradi.

import gc 

# Creating objects
x = [1, 2, 3]
y = x # Reference count for list is now 2 

# Check if object is tracked by garbage collector
print(gc.is_tracked(x)) # True 

# Delete reference
del x # Reference count decreases to 1 

# Force garbage collection
collected = gc.collect()
print(f"Collected {collected} objects") 

# Check garbage collection stats
print(gc.get_stats())

Keng tarqalgan xatolar va maslahatlar:

  • del xotirani darhol bo'shatadi deb o'ylash. U faqat reference count'ni kamaytiradi; xotirani aslida qachon bo'shatishni garbage collector hal qiladi.

  • Circular reference'lardan bexabar bo'lish: ular avtomatik tozalashga to'sqinlik qilishi va cyclic garbage collector'ni talab qilishi mumkin.

  • Xotirani ko'p talab qiladigan ilovalar (masalan, machine learning) bilan ishlayotgan holatlardan tashqari gc.collect()'ni qo'lda chaqirmang. Bu hali bo'shatilmagan, ammo endi kerak bo'lmagan murakkab obyektlar egallab turgan xotirani bo'shatishga yordam beradi.

Python'da argumentlar qanday uzatiladi: by value yoki by reference?

Python'da pass by object reference (boshqacha aytganda, “pass by assignment”) qo'llaniladi: funksiya obyektga reference oladi, ammo o'zgarishlar saqlanib qolish-qolmasligi mutability'ga bog'liq:

  • Agar obyekt immutable bo'lsa (int, str, tuple kabi), funksiya ichida qayta qiymat berish asl obyektni o'zgartirmaydi.

  • Agar obyekt mutable bo'lsa (list, dict kabi), joyida qilingan o'zgarishlar asl obyektga ta'sir qiladi.

Asosiysi — siz o'zgaruvchining o'zini emas, balki obyektga reference'ni uzatayotganingizni tushunish.

def modify_immutable(x):
    x = x + 10  # Creates new object, doesn't affect original
    return x

def modify_mutable(lst):
    lst.append(4)  # Modifies the original object
    return lst

def reassign_mutable(lst):
    lst = [7, 8, 9]  # Creates new local reference, doesn't affect original
    return lst

# Immutable example
num = 5
result = modify_immutable(num)
print(num)     # 5 (unchanged)
print(result)  # 15

# Mutable example - modification
my_list = [1, 2, 3]
modify_mutable(my_list)
print(my_list)  # [1, 2, 3, 4] (changed)

# Mutable example - reassignment
my_list2 = [1, 2, 3]
result = reassign_mutable(my_list2)
print(my_list2)  # [1, 2, 3] (unchanged)
print(result)    # [7, 8, 9]

Keng tarqalgan xatolar va maslahatlar:

  • Funksiyaga uzatilgan immutable obyektlar o'zgaradi deb kutish — ular asl obyektni o'zgartirish o'rniga yangi obyekt yaratadi.

  • Mutable obyektlar funksiya ichida o'zgarganda hayron qolish — funksiya aynan o'sha obyektga reference oladi.

  • Qayta qiymat berishni o'zgartirish bilan adashtirish — lst = [1, 2, 3] yangi local reference yaratadi, lst.append(4) esa asl obyektni o'zgartiradi.

Python'da dictionary comprehension nima?

Dictionary comprehension — mavjud iterable'dan dictionary yaratish yoki mavjud dictionary'larni o'zgartirishning ixcham usuli. Loop yozish o'rniga siz key'ni ham, value'ni ham bitta expression'da aniqlaysiz. Aslida bu list comprehension'ning o'zi, faqat u key-value juftliklarini hosil qiladi.

# Basic dictionary comprehension
squares = {x: x**2 for x in range(5)}
print(squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# With condition
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares)  # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

# Transform existing dictionary
prices = {'apple': 0.5, 'banana': 0.3, 'orange': 0.6}
price_increase = {item: price * 1.1 for item, price in prices.items()}

# Swap keys and values
reversed_dict = {v: k for k, v in prices.items()}

Keng tarqalgan xatolar va maslahatlar:

  • Takrorlanuvchi key'lar bilan dictionary yaratish (oxirgi value saqlanib qoladi).

  • Comprehension'larni haddan tashqari murakkablashtirish. Agar u o'qilishi qiyin bo'lsa, oddiy loop'dan foydalaning.

Bu savollar Python'ni asoslardan chuqurroq tushunishingizni tekshiradi. Hiring manager'lar funksiyalar, sinflar hamda decorator'lar va generator'lar kabi Python'ning o'ziga xos imkoniyatlari bilan ishlay olishingizni ko'rishni xohlaydi.

O'rta darajadagi Python intervyu savollari

Oddiy funksiya va lambda funksiya o'rtasida qanday farq bor?

Oddiy funksiyalar def bilan aniqlanadi; ular bir nechta statement'dan iborat bo'lishi, nomga ega bo'lishi va hujjatlashtirish matnini o'z ichiga olishi mumkin. Lambda funksiyalar esa o'zidagi expression natijasini qaytaradigan anonymous funksiyalardir.

Lambda funksiyalar bir qatorda ifodalash mumkin bo'lgan oddiy amallar uchun, ayniqsa map(), filter() yoki sort() amallari uchun tezkor funksiya kerak bo'lganda eng mos keladi. Bir nechta statement yoki murakkab mantiq kerak bo'lganda, yoxud funksiyani ko'p marta qayta ishlatmoqchi bo'lsangiz, oddiy funksiyalar yaxshiroq.

# Lambda function - single expression only
square_lambda = lambda x: x ** 2

print(square(5))        # 25
print(square_lambda(5)) # 25

# Where lambdas shine - with higher-order functions
numbers = [1, 2, 3, 4, 5]

# Using lambda with map
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # [1, 4, 9, 16, 25]

# Using lambda with filter
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4]

# Using lambda with sorted
students = [
    {'name': 'Alice', 'grade': 85},
    {'name': 'Bob', 'grade': 92},
    {'name': 'Charlie', 'grade': 78}
]
sorted_students = sorted(students, key=lambda s: s['grade'])
print(sorted_students[0]['name'])  # Charlie (lowest grade)

# When NOT to use lambda
# Bad - too complex for lambda
process = lambda x: x.strip().lower().replace(' ', '_') if x else ''

# Good - use normal function for clarity
def process_string(x):
    if not x:
        return ''
    return x.strip().lower().replace(' ', '_')

Keng tarqalgan xatolar va maslahatlar:

  • Lambda'ga bir nechta statement kiritishga urinish (ular faqat expression'lardan iborat bo'la oladi).

  • Oddiy funksiya aniqroq bo'ladigan joyda lambda ishlatish.

  • Lambda'larni o'zgaruvchilarga biriktirish ularning anonymous bo'lish maqsadini yo'qqa chiqaradi.

O'zgaruvchan sonli argument qabul qiladigan Python funksiyasi qanday aniqlanadi?

Python o'zgaruvchan sonli argumentlar bilan ishlash uchun ikkita maxsus operator taqdim etadi: positional argument'lar uchun *args va keyword argument'lar uchun **kwargs. Bu funksiyalaringizga qancha argument uzatilishini aniq bilmagan holda ham moslashuvchan kirish ma'lumotlarini qabul qilish imkonini beradi.

# *args collects positional arguments into a tuple
def sum_all(*args):
    total = 0
    for num in args:
        total += num
    return total

print(sum_all(1, 2, 3))        # 6
print(sum_all(1, 2, 3, 4, 5))  # 15

# **kwargs collects keyword arguments into a dictionary
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=30, city="NYC")
# Output:
# name: Alice
# age: 30
# city: NYC

# Combining regular args, *args, and **kwargs
def flexible_function(required, *args, **kwargs):
    print(f"Required: {required}")
    print(f"Extra positional: {args}")
    print(f"Keyword arguments: {kwargs}")

flexible_function("hello", 1, 2, 3, name="Bob", age=25)
# Output:
# Required: hello
# Extra positional: (1, 2, 3)
# Keyword arguments: {'name': 'Bob', 'age': 25}

# Unpacking arguments when calling functions
def multiply(a, b, c):
    return a * b * c

numbers = [2, 3, 4]
print(multiply(*numbers))  # 24 - unpacks list into arguments

config = {'a': 2, 'b': 3, 'c': 4}
print(multiply(**config))  # 24 - unpacks dict into keyword arguments

Keng tarqalgan xatolar va maslahatlar:

  • Tartib muhim: avval oddiy argumentlar, keyin *args, keyin keyword argument'lar, so'ngra **kwargs.

  • *args list emas, tuple yaratadi.

  • List/dict'larni funksiyalarga uzatishda unpack qilishni unutish.

yield keyword'i nima va u qanday ishlaydi?

yield keyword'i funksiyani generator'ga aylantiradi; generator barcha qiymatlarni birdaniga qaytarish o'rniga ularni birma-bir hosil qiladi. Funksiya yield'ni o'z ichiga olganda, u iterate qilish mumkin bo'lgan generator obyektini qaytaradi va har bir yield nuqtasida bajarilishni to'xtatib, keyin davom ettiradi.

Generator'lar xotirani tejaydi, chunki ular barcha qiymatlarni xotirada saqlamaydi. Ular har bir qiymatni kerak bo'lgan paytda hisoblab, hosil qiladi, bu esa ularni katta dataset'lar yoki cheksiz ketma-ketliklar uchun ideal qiladi.

# Regular function returns all values at once
def get_squares_list(n):
    result = []
    for i in range(n):
        result.append(i ** 2)
    return result  # Returns entire list

# Generator function yields values one at a time
def get_squares_generator(n):
    for i in range(n):
        yield i ** 2  # Pauses here, returns one value

# Memory difference
import sys
list_squares = get_squares_list(1000)
gen_squares = get_squares_generator(1000)

print(sys.getsizeof(list_squares))  # ~8856 bytes
print(sys.getsizeof(gen_squares))   # ~112 bytes

# How yield works - function state is preserved
def countdown(n):
    print(f"Starting countdown from {n}")
    while n > 0:
        yield n  # Pause and return n
        n -= 1
    print("Countdown finished!")

# Using the generator
counter = countdown(3)
print(next(counter))  # "Starting countdown from 3" then returns 3
print(next(counter))  # Returns 2
print(next(counter))  # Returns 1
# next(counter)  # "Countdown finished!" then raises StopIteration

Keng tarqalgan xatolar va maslahatlar:

  • Generator'lar bir martalik; ular tugagach, yangisini yaratishingiz kerak.

  • Generator'ga list() qo'llash uning xotirani tejash maqsadini yo'qqa chiqaradi.

  • Generator'lar lazy ekanini va iterate qilinmaguncha bajarilmasligini unutish.

Python'ning magic (dunder) method'lari nima?

Magic method'lar ("double underscore" iborasidan kelib chiqib, dunder method'lar deb ham ataladi) — Python muayyan vaziyatlarda avtomatik chaqiradigan maxsus method'lar. Ular obyektlaringiz qo'shish, taqqoslash, string ko'rinishida ifodalash va iteration kabi built-in operatsiyalar bilan qanday ishlashini belgilash imkonini beradi.

class Book:
    def __init__(self, title, author, pages):
        self.title = title
        self.author = author
        self.pages = pages

    # String representation
    def __str__(self):
        return f"{self.title} by {self.author}"

    def __repr__(self):
        return f"Book('{self.title}', '{self.author}', {self.pages})"

    # Comparison methods
    def __eq__(self, other):
        if not isinstance(other, Book):
            return False
        return self.title == other.title and self.author == other.author

    def __lt__(self, other):
        return self.pages < other.pages

    # Arithmetic operations
    def __add__(self, other):
        return Book(
            f"{self.title} & {other.title}",
            f"{self.author} & {other.author}",
            self.pages + other.pages
        )

    # Container behavior
    def __len__(self):
        return self.pages

    def __contains__(self, keyword):
        return keyword.lower() in self.title.lower()

# Using magic methods
book1 = Book("Python Tricks", "Dan Bader", 300)
book2 = Book("Fluent Python", "Luciano Ramalho", 750)

print(str(book1))         # Python Tricks by Dan Bader
print(repr(book1))        # Book('Python Tricks', 'Dan Bader', 300)
print(book1 == book2)     # False
print(book1 < book2)      # True (300 < 750)
print(len(book1))         # 300
print("python" in book1)  # True

Keng tarqalgan xatolar va maslahatlar:

  • eq'ni hash'siz amalga oshirish obyektni dictionary/set'da ishlatishni buzadi.

  • Qo'llab-quvvatlanmaydigan operatsiyalar uchun NotImplemented qaytarmaslik.

  • Obyektni qayta yaratib bo'lmaydigan repr natijasini qaytarish.

Ilg'or tushunchalar

Global Interpreter Lock (GIL) nima va u nega muhim?

Global Interpreter Lock — Python obyektlariga murojaatni himoya qiladigan mutex bo'lib, u bir nechta thread'ning Python bytecode'ini bir vaqtda bajarishiga yo'l qo'ymaydi. Hatto ko'p yadroli tizimlarda ham bir vaqtning o'zida faqat bitta thread Python kodini bajara oladi.

GIL Python'ning memory management'i thread-safe bo'lmagani uchun mavjud. U reference counting va garbage collection jarayonida race condition'larning oldini oladi. GIL Python implementatsiyasini soddalashtirsa-da, bu CPU-bound vazifalar threading'dan foyda ko'rmasligini anglatadi.

import threading
import time

# CPU-bound task affected by GIL
def cpu_bound_task(n):
    result = 0
    for i in range(n * 1000000):
        result += i ** 2
    return result

# I/O-bound task not affected by GIL
def io_bound_task():
    time.sleep(1)  # Releases GIL during sleep
    return "Done"

# Threading with CPU-bound tasks (limited by GIL)
start = time.time()
threads = []
for i in range(4):
    t = threading.Thread(target=cpu_bound_task, args=(100,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()
print(f"Threading CPU-bound: {time.time() - start:.2f}s")

# Multiprocessing bypasses GIL
from multiprocessing import Pool
start = time.time()
with Pool(4) as pool:
    pool.map(cpu_bound_task, [100] * 4)
print(f"Multiprocessing CPU-bound: {time.time() - start:.2f}s")

Keng tarqalgan xatolar va maslahatlar:

  • Python'da threading hech qachon foyda bermaydi deb o'ylash. U I/O-bound vazifalar uchun juda yaxshi, chunki I/O operatsiyalari paytida GIL bo'shatiladi.

  • Multiprocessing yaxshiroq bo'ladigan CPU-intensive ishlar uchun threading'dan foydalanish.

Python'da memory allocation qanday ishlaydi?

Python xotirani barcha obyektlar va ma'lumotlar tuzilmalari joylashadigan private heap yordamida avtomatik boshqaradi. Python Memory Manager bu heap'ni nazorat qiladi va qachon joy ajratish yoki bo'shatishni hal qiladi. Uning ostida esa low-level xotirani operatsion tizim taqdim etadi.

Python, shuningdek, ayrim immutable obyektlar (kichik integer'lar va qisqa string'lar kabi) uchun object pooling'dan foydalanadi, shunda ular qayta yaratilish o'rniga qayta ishlatiladi va bu unumdorlikni oshiradi.

import sys

# Small integers are cached (-5 to 256)
a = 100
b = 100
print(a is b)  # True (same object in memory)

# Large integers create new objects
c = 1000
d = 1000
print(c is d)  # False (different objects)

# String interning for efficiency
str1 = "hello"
str2 = "hello"
print(str1 is str2)  # True (interned)

# Check object size in memory
my_list = [1, 2, 3, 4, 5]
print(f"List size: {sys.getsizeof(my_list)} bytes")

# Memory growth example
small_list = []
print(f"Empty list: {sys.getsizeof(small_list)} bytes")

small_list.extend(range(100))
print(f"100 items: {sys.getsizeof(small_list)} bytes")

# Python pre-allocates more space than needed for efficiency
small_list = [1]
print(f"One item: {sys.getsizeof(small_list)} bytes")

Keng tarqalgan xatolar va maslahatlar:

  • Reference'larni o'chirganingizda Python xotirani darhol bo'shatadi deb o'ylash. Xotirani aslida qachon bo'shatishni garbage collector hal qiladi.

  • Python tez-tez qayta joy ajratishning oldini olish uchun dinamik tuzilmalarga keragidan ko'proq joy ajratishini tushunmaslik.

Python'da multithreading va multiprocessing nima?

Multithreading bitta process ichidagi thread'lardan foydalanadi va xotira ular o'rtasida umumiy bo'ladi, ammo CPU-bound vazifalarda u GIL bilan cheklangan. Multiprocessing mustaqil xotira maydonlariga ega alohida process'lardan foydalanadi va GIL'ni chetlab o'tadi, lekin process'lar o'rtasidagi aloqa uchun overhead yuqoriroq bo'ladi.

import threading
import multiprocessing
import time
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor

def cpu_intensive_task(n):
    # CPU-bound task
    result = sum(i * i for i in range(n))
    return result

def io_intensive_task(delay):
    # I/O-bound task
    time.sleep(delay)
    return f"Task completed after {delay}s"

# Threading example (good for I/O-bound tasks)
def test_threading():
    start = time.time()
    with ThreadPoolExecutor(max_workers=4) as executor:
        # I/O-bound tasks benefit from threading
        futures = [executor.submit(io_intensive_task, 1) for _ in range(4)]
        results = [f.result() for f in futures]
    print(f"Threading I/O: {time.time() - start:.2f}s")

    start = time.time()
    with ThreadPoolExecutor(max_workers=4) as executor:
        # CPU-bound tasks limited by GIL
        futures = [executor.submit(cpu_intensive_task, 1000000) for _ in range(4)]
        results = [f.result() for f in futures]
    print(f"Threading CPU: {time.time() - start:.2f}s")

# Multiprocessing example (good for CPU-bound tasks)
def test_multiprocessing():
    start = time.time()
    with ProcessPoolExecutor(max_workers=4) as executor:
        # CPU-bound tasks benefit from multiprocessing
        futures = [executor.submit(cpu_intensive_task, 1000000) for _ in range(4)]
        results = [f.result() for f in futures]
    print(f"Multiprocessing CPU: {time.time() - start:.2f}s")

Keng tarqalgan xatolar va maslahatlar:

  • Parallelism kutib, CPU-bound vazifalar uchun threading'dan foydalanish.

  • Thread'larga nisbatan process yaratish overhead'i qanchalik katta ekanini tushunmaslik.

  • Process'lar odatiy holatda xotirani bo'lishmasligini unutish.

Xotiradagi mavjud obyekt bilan qanday qilib samarali ishlash mumkin?

Obyektlar bilan ishlash Python'ning memory model'ini tushunish, mos ma'lumotlar tuzilmalaridan foydalanish, obyekt yaratishni minimallashtirish, imkon qadar obyektlarni qayta ishlatish va circular reference'lar keltirib chiqaradigan memory leak'lardan xabardor bo'lishni o'z ichiga oladi.

import sys
import array
from weakref import WeakValueDictionary

# Object pooling for reuse
class ObjectPool:
    def __init__(self, factory):
        self._factory = factory
        self._pool = []

    def acquire(self):
        return self._pool.pop() if self._pool else self._factory()

    def release(self, obj):
        self._pool.append(obj)

# Memory-efficient data structures
int_list = [1, 2, 3, 4, 5]
int_array = array.array('i', [1, 2, 3, 4, 5])
print(f"List: {sys.getsizeof(int_list)} bytes")
print(f"Array: {sys.getsizeof(int_array)} bytes")

# Efficient string operations
def build_string_bad(items):
    result = ""
    for item in items:
        result += str(item) + ", "
    return result.rstrip(", ")

def build_string_good(items):
    return ", ".join(str(item) for item in items)

# Weak references for caching
class CacheManager:
    def __init__(self):
        self._cache = WeakValueDictionary()

    def get_object(self, key, factory):
        obj = self._cache.get(key)
        if obj is None:
            obj = factory()
            self._cache[key] = obj
        return obj

Keng tarqalgan xatolar va maslahatlar:

  • Loop'lar ichida obyektlarni qayta ishlatish o'rniga keraksiz obyektlar yaratish.

  • Array'lar samaraliroq bo'ladigan bir xil turdagi sonli ma'lumotlar uchun list'lardan foydalanish.

  • Garbage collection'ga to'sqinlik qiladigan circular reference'lardan bexabar bo'lish.

Bu savollar bosim ostida muammolarni hal qilish ko'nikmalaringizni hamda toza va samarali Python kodi yoza olishingizni tekshiradigan amaliy loyihalardir. Hiring manager'lar ulardan muammolarga qanday yondashishingiz, edge case'larni qanday hal qilishingiz va yechimlarni qanday optimallashtirishingizni ko'rish uchun foydalanadi. Ular shunchaki ishlaydigan kodni izlamaydi; ular kuchli kod yozish ko'nikmalaringizni va ma'lumotlar tuzilmalarini tushunishingizni ko'rsatadigan, o'qilishi oson va qo'llab-quvvatlash qulay yechimlar yoza olishingizni ko'rishni xohlaydi.

Kodlash topshiriqlari

Ma'lumotlar tuzilmalari yordamida LRU cache'ni amalga oshiring

LRU (Least Recently Used) cache kesh to'lganda eng uzoq vaqtdan beri ishlatilmagan elementni chiqarib tashlaydi. Asosiy qiyinchilik — get va put operatsiyalarining ikkalasi uchun ham O(1) time complexity'ni saqlab qolish.

from collections import OrderedDict

# Simple approach using OrderedDict
class LRUCache:
    def __init__(self, capacity):
        self.cache = OrderedDict()
        self.capacity = capacity

    def get(self, key):
        if key not in self.cache:
            return -1
        # Move to end (most recent)
        self.cache.move_to_end(key)
        return self.cache[key]

    def put(self, key, value):
        if key in self.cache:
            self.cache.move_to_end(key)
        self.cache[key] = value
        if len(self.cache) > self.capacity:
            # Remove least recently used (first item)
            self.cache.popitem(last=False)

# Usage example
cache = LRUCache(2)
cache.put(1, 1)
cache.put(2, 2)
print(cache.get(1))  # Returns 1
cache.put(3, 3)      # Evicts key 2
print(cache.get(2))  # Returns -1 (not found)

Keng tarqalgan xatolar va maslahatlar:

  • Ikkala ma'lumotlar tuzilmasini (hash map va linked list) to'g'ri yuritmaslik.

  • Node'larni ko'chirishda pointer'larni yangilashni unutish.

  • Mavjud key yangilanayotgan holatni hisobga olmaslik.

Pandas kutubxonasi nima va u NumPy bilan qanday taqqoslanadi?

Pandas NumPy ustiga qurilgan bo'lib, ma'lumotlar tahlili uchun high-level ma'lumotlar tuzilmalari va vositalarni taqdim etadi. NumPy matematik operatsiyalar va ilmiy hisoblashlar uchun; Pandas esa data cleaning, ma'lumotlarni o'rganish, time series tahlili va data visualization workflow'lari uchun line plot'lar yaratishda ishlatiladi.

import pandas as pd
import numpy as np

# NumPy: homogeneous numerical arrays
np_array = np.array([[1, 2, 3], [4, 5, 6]])
print(np_array * 2)  # Element-wise multiplication

# Pandas: labeled, heterogeneous data
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 30, 35],
    'salary': [50000, 60000, 70000]
})
print(df.head())

# Key differences demonstrated

# 1. Indexing
# NumPy uses integer positions
print(np_array[0, 1])  # 2

# Pandas uses labels
df.set_index('name', inplace=True)
print(df.loc['Alice', 'age'])  # 25

# 2. Missing data handling
# NumPy doesn't handle missing data well
np_with_nan = np.array([1, 2, np.nan, 4])
print(np_with_nan.mean())  # nan

# Pandas handles missing data gracefully
series = pd.Series([1, 2, None, 4])
print(series.mean())  # 2.333... (ignores NaN)

# 3. Data alignment
series1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
series2 = pd.Series([4, 5, 6], index=['b', 'c', 'd'])
print(series1 + series2)  # Aligns by index automatically

# 4. Time series functionality
dates = pd.date_range('2024-01-01', periods=5)
ts = pd.Series(np.random.randn(5), index=dates)
print(ts.resample('2D').mean())  # Resample to 2-day periods

Keng tarqalgan xatolar va maslahatlar:

  • Sof sonli hisoblashlar uchun Pandas'dan foydalanish (NumPy tezroq).

  • Pandas Series/DataFrame ichida NumPy array'lari borligini tushunmaslik.

  • Kichik dataset'lar uchun Pandas'ning xotira overhead'ini e'tiborsiz qoldirish.

Pandas'da ikki yoki undan ortiq DataFrame'ni qanday birlashtirish mumkin?

DataFrame'larni birlashtirish turli manbalardagi ma'lumotlarni jamlash uchun zarur. Pandas ma'lumotlarni qanday birlashtirmoqchi ekaningizga qarab bir nechta method taqdim etadi.

import pandas as pd

# Create sample DataFrames
df1 = pd.DataFrame({
    'id': [1, 2, 3, 4],
    'name': ['Alice', 'Bob', 'Charlie', 'David'],
    'department': ['Sales', 'IT', 'HR', 'Sales']
})

df2 = pd.DataFrame({
    'id': [2, 3, 4, 5],
    'salary': [60000, 55000, 62000, 58000],
    'bonus': [5000, 3000, 4000, 3500]
})

df3 = pd.DataFrame({
    'department': ['Sales', 'IT', 'HR'],
    'budget': [100000, 150000, 80000]
})

# 1. merge() - Database-style joins
# Inner join (default) - only matching records
inner_merge = pd.merge(df1, df2, on='id')
print(inner_merge)  # Only ids 2, 3, 4

# Left join - all from left DataFrame
left_merge = pd.merge(df1, df2, on='id', how='left')
print(left_merge)  # All from df1, NaN for missing df2 data

# Right join - all from right DataFrame  
right_merge = pd.merge(df1, df2, on='id', how='right')

# Outer join - all from both
outer_merge = pd.merge(df1, df2, on='id', how='outer')

# Merge on multiple columns
df_merged = pd.merge(df1, df3, on='department')

# Different column names
df2_renamed = df2.rename(columns={'id': 'emp_id'})
merged = pd.merge(df1, df2_renamed, left_on='id', right_on='emp_id')

# 2. join() - Index-based joining
df1_indexed = df1.set_index('id')
df2_indexed = df2.set_index('id')
joined = df1_indexed.join(df2_indexed)

# 3. concat() - Stack DataFrames
# Vertical concatenation (stack rows)
df_same_cols = pd.DataFrame({
    'id': [5, 6],
    'name': ['Eve', 'Frank'],
    'department': ['IT', 'HR']
})
vertical_concat = pd.concat([df1, df_same_cols], ignore_index=True)

# Horizontal concatenation (side by side)
horizontal_concat = pd.concat([df1, df2], axis=1)

# Merge multiple DataFrames
from functools import reduce

dfs = [df1, df2, df3]
merged_all = reduce(lambda left, right: pd.merge(left, right, on='id', how='outer'), dfs)

# Handling duplicate column names
df_merged = pd.merge(df1, df2, on='id', suffixes=('_left', '_right'))

Keng tarqalgan xatolar va maslahatlar:

  • Join turini aniq ko'rsatmaslik (odatiy holatda inner join ishlatiladi).

  • Takrorlanuvchi ustun nomlarini hal qilishni unutish.

  • Katta DataFrame'larni birlashtirishda xotira bilan bog'liq muammolar.

Python'da matnli faylni qanday o'qish va qayta ishlash mumkin?

Matnli faylni o'qish va qayta ishlash ko'plab kodlash topshiriqlari va amaliy vaziyatlarda tekshiriladigan asosiy ko'nikma.

# Method 1: Using with statement (recommended)
with open('data.txt', 'r') as file:
    content = file.read()  # Read entire file
    # File automatically closed after this block

# Method 2: Read line by line (memory efficient)
with open('data.txt', 'r') as file:
    for line in file:
        process_line(line.strip())  # Remove newline

# Method 3: Read all lines into a list
with open('data.txt', 'r') as file:
    lines = file.readlines()  # List of lines with \n

# Method 4: Read specific number of characters
with open('data.txt', 'r') as file:
    chunk = file.read(1024)  # Read 1024 characters

# Writing to file
with open('output.txt', 'w') as file:
    file.write("Hello, World!\n")

# Append to file
with open('log.txt', 'a') as file:
    file.write(f"Log entry: {timestamp}\n")

# Handle encoding
with open('data.txt', 'r', encoding='utf-8') as file:
    text = file.read()
# Word frequency counter (common interview question)
word_count = {}
with open('text.txt', 'r') as file:
    for line in file:
        words = line.strip().split()
        for word in words:
            word_count[word] = word_count.get(word, 0) + 1

Keng tarqalgan xatolar:

  • Fayllarni yopishni unutish (with statement'dan foydalaning).

Loading huge files entirely into memory instead of processing line by line.

  • ASCII bo'lmagan matnda encoding muammolarini hal qilmaslik.

Fayllar bilan ishlashga oid savollar data analyst lavozimlari uchun keng tarqalgan, chunki bu ishda CSV fayllar va log'larni qayta ishlash odatiy vazifa hisoblanadi.

Yakuniy fikrlar: Shunchaki ko'proq emas, aqlliroq tayyorlaning

Birinchi junior dev lavozimingizni nishonga olayotgan bo'lasizmi yoki senior lavozimga ko'tarilmoqchimisiz, Python intervyulari syntax'dan ko'ra ko'proq narsani tekshiradi. Ular qanchalik yaxshi fikrlashingizni, muammolarni qanday hal qilishingizni va toza, samarali yechimlar yaratish uchun tildan qanday foydalanishingizni baholaydi.

Kareraning qaysi bosqichida bo'lishingizdan qat'i nazar, biz yordam berishga tayyormiz. Bizning Python developer roadmap'imizni ko'rib chiqishingizni qat'iy tavsiya qilamiz. Uni eng oddiy syntax'dan tortib ilg'or tushunchalargacha Python olamining murakkabliklarida yo'l topishga yordam beradigan foydali vosita — kompas deb biling.

Ammo o'rganish yo'lida siz yolg'iz bo'lmaysiz. Bizning AI tutor'imiz sizga hamrohlik qiladi va tayyorgarligingizni yo'naltirib boradi. U ko'nikma darajangizga moslashadi, sizga moslashtirilgan topshiriqlar beradi va keng tarqalgan xatolardan qochishga yordam beradi. Uni mashq hamkoringiz deb biling: qiyin joyga kelib qolganingizda unga savollar bering, turli misollarni sinab ko'ring va tushunchalar to'liq anglanmaguncha yangi kod bilan o'zingizni sinashda davom eting. Shunday qilib, intervyularga to'liq ishonch bilan kirib borasiz.

Yo'l xaritalariQo'llanmalarFAQYouTube

yo'lxaritaroadmap.shasosida

Hamjamiyat tomonidan yaratilgan yo'l xaritalari, eng yaxshi amaliyotlar, loyihalar, maqolalar, manbalar va yo'nalishlar — o'z yo'lingizni tanlash va kasbingizda o'sish uchun.

© yo'lxarita·Shartlar·Maxfiylik·

roadmap.sh

Barcha kontent roadmap.sh loyihasidan olingan (© Kamran Ahmed) va shaxsiy o'rganish uchun o'zbek tiliga tarjima qilinmoqda.

Qidiruv

Yo'l xaritalari, loyihalar va savollarni qidiring