Azimjon Abdurasulov

Swift Tili

Interview Savollari

Swift Tili — Interview Savollari va Javoblari

Ushbu qo'llanmada Swift dasturlash tili bo'yicha eng ko'p so'raladigan 50 ta savol va javoblar jamlangan. Bu savollar iOS'ga emas, balki tilning o'ziga — sintaksis, xotira, turlar tizimi va ilg'or xususiyatlarga bag'ishlangan.


1. Turlar va Asosiy Tuzilmalar

1. Value Type va Reference Type farqi nima?

Javob:

  • Value Type (struct, enum, tuple): Nusxa olinganda ma'lumotning o'zi ko'chiriladi. Har bir nusxa mustaqil.
  • Reference Type (class, closure): Nusxa olinganda faqat havola (pointer) ko'chiriladi. Barcha nusxalar bitta obyektga ishora qiladi.
// Value Type
var a = [1, 2, 3]
var b = a       // b — mustaqil nusxa
b.append(4)
print(a) // [1, 2, 3] — a o'zgarmadi

// Reference Type
class Box { var value = 0 }
let box1 = Box()
let box2 = box1  // box2 — havola (pointer)
box2.value = 42
print(box1.value) // 42 — box1 ham o'zgardi!

2. struct va class qachon ishlatiladi?

Javob:

  • Struct ishlatish (default tanlov): Ma'lumot modellari, konfiguratsiyalar, kichik obyektlar. Thread-safe.
  • Class ishlatish: Merosxo'rlik kerak bo'lganda, identlik (===) kerak bo'lganda, yoki Objective-C API bilan ishlashda.

💡 Apple tavsiyasi: Avval struct ishlating, faqat zarur bo'lganda class'ga o'ting.

3. let va var farqi?

Javob:

  • let — konstanta (o'zgarmas). Bir marta qiymat berilsa, o'zgartirib bo'lmaydi.
  • var — o'zgaruvchi. Istalgan vaqtda yangi qiymat berish mumkin.

⚠️ Muhim: Class obyekti let bilan e'lon qilinsa ham, uning property'larini o'zgartirish mumkin (chunki reference type).

4. Optional nima va u qanday ishlaydi?

Javob: Optional — bu "qiymat bor yoki yo'q" holatini ifodalovchi enum:

// Optional aslida shu
enum Optional<Wrapped> {
    case some(Wrapped)  // Qiymat bor
    case none           // nil — qiymat yo'q
}

Xavfsiz ochish usullari:

  • if let — qavs ichida ishlaydi
  • guard let — funktisyadan erta chiqish
  • ?? (nil-coalescing) — default qiymat
  • ?. (optional chaining) — zanjirli murojaat

5. Type Inference nima?

Javob: Swift kompilyatori o'zgaruvchining turini qiymatiga qarab avtomatik aniqlaydi:

let name = "Ali"    // Swift biladi: bu String
let age = 25        // Swift biladi: bu Int
let price = 9.99    // Swift biladi: bu Double

6. Tuple nima va qachon ishlatiladi?

Javob: Bir nechta qiymatni bitta guruhga yig'ish. Struct yaratish kerak bo'lmagan oddiy holatlarda:

let result = (code: 200, message: "OK")
print(result.code)    // 200
print(result.message) // "OK"

// Funksiyadan ikki qiymat qaytarish
func divide(_ a: Int, _ b: Int) -> (quotient: Int, remainder: Int) {
    return (a / b, a % b)
}

7. typealias nima?

Javob: Mavjud turga yangi, tushunarli nom berish:

typealias UserID = String
typealias CompletionHandler = (Result<Data, Error>) -> Void

func fetchUser(id: UserID, completion: CompletionHandler) { }

8. Any, AnyObject, AnyHashable farqi?

Javob:

  • Any — istalgan tur (value type, reference type, function, closure).
  • AnyObject — faqat class obyektlari.
  • AnyHashable — faqat Hashable protokoliga mos turlar.

2. Funksiyalar va Closures

9. First-class functions nima degani?

Javob: Swift'da funksiyalar birinchi sinf fuqarolar (first-class citizens). Ularni:

  • O'zgaruvchiga saqlash mumkin
  • Boshqa funksiyaga parametr sifatida uzatish mumkin
  • Funksiyadan qaytarish mumkin
let greet: (String) -> String = { name in "Salom, \(name)!" }
print(greet("Ali")) // "Salom, Ali!"

10. Closure nima va funksiyadan farqi?

Javob: Closure — bu nomsiz funksiya. U o'zi yaratilgan kontekstdagi o'zgaruvchilarni "capture" (ushlab olish) qila oladi:

func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1  // ← tashqi o'zgaruvchini "capture" qildi
        return count
    }
}

let counter = makeCounter()
print(counter()) // 1
print(counter()) // 2

11. @escaping va @non-escaping closure?

Javob:

  • Non-escaping (default): Closure funksiya ichida ishlaydi va bitadi.
  • @escaping: Closure funksiya tugaganidan keyin ham saqlanadi (masalan, API callback).
// @escaping — closure keyinroq chaqiriladi
func fetchData(completion: @escaping (Data) -> Void) {
    DispatchQueue.global().async {
        let data = Data()
        completion(data) // Funksiya allaqachon tugagan, lekin closure hali ishlayapti
    }
}

12. Trailing Closure sintaksisi?

Javob: Funksiyaning oxirgi parametri closure bo'lsa, uni qavsdan tashqariga yozish mumkin:

// Oddiy ko'rinish
numbers.filter({ $0 > 5 })

// Trailing closure
numbers.filter { $0 > 5 }

// Ko'p closure bo'lsa
UIView.animate(withDuration: 0.3) {
    view.alpha = 0
} completion: { _ in
    view.removeFromSuperview()
}

13. $0, $1 nima?

Javob: Closure parametrlarining qisqartma nomlari. $0 — birinchi parametr, $1 — ikkinchi:

let sorted = names.sorted { $0 < $1 }
let doubled = numbers.map { $0 * 2 }

14. Capture List ([weak self], [unowned self]) nima?

Javob:

  • [weak self] — self'ni zaif ushlab, Optional qiladi. Self yo'q bo'lib ketsa — nil. Eng xavfsiz.
  • [unowned self] — self yo'q bo'lsa crash beradi. Faqat self doim mavjud ekani kafolatlangan holda.

3. Enum, Protocol va Generics

15. Swift Enum nima va qanday afzalliklari bor?

Javob: Swift'dagi Enum boshqa tillardan ancha kuchli:

enum NetworkResult {
    case success(data: Data)           // Associated Value
    case failure(error: Error, code: Int)
    case loading(progress: Double)
    
    var isComplete: Bool {            // Computed property
        if case .success = self { return true }
        return false
    }
}

16. Associated Values vs Raw Values?

Javob:

  • Associated Values: Har bir case'ga turli turdagi qo'shimcha ma'lumot biriktirish.
  • Raw Values: Har bir case'ga bir xil turdagi doimiy qiymat berish.
// Raw Value
enum Planet: Int {
    case mercury = 1, venus, earth, mars
}
print(Planet.earth.rawValue) // 3

// Associated Value
enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

17. Protocol nima?

Javob: Protocol — bu "shartnoma" (contract). Protokolga mos keladigan har qanday tur belgilangan metodlar va property'larni implementatsiya qilishi shart:

protocol Drawable {
    var color: String { get }
    func draw()
}

struct Circle: Drawable {
    var color = "Red"
    func draw() { print("Drawing circle") }
}

18. Protocol Extension va Default Implementation?

Javob: Protokolga default (standart) amal yozish mumkin:

protocol Greetable {
    var name: String { get }
    func greet() -> String
}

extension Greetable {
    func greet() -> String {  // Default implementation
        return "Salom, \(name)!"
    }
}

struct User: Greetable {
    let name: String
    // greet() yozmasak ham ishlaydi — default amal bor
}

19. Generics nima va nega kerak?

Javob: Har xil turlar bilan ishlaydigan universal kod yozish:

// Generics YO'Q — har tur uchun alohida yozish kerak
func swapInts(_ a: inout Int, _ b: inout Int) { let temp = a; a = b; b = temp }
func swapStrings(_ a: inout String, _ b: inout String) { let temp = a; a = b; b = temp }

// Generics BILAN — bitta funksiya yetarli
func swap<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}

20. Generic Constraints (where) nima?

Javob: Generic turga cheklov qo'yish:

// T faqat Comparable bo'lsa ishlaydi
func findMax<T: Comparable>(_ array: [T]) -> T? {
    return array.max()
}

// Murakkab cheklov
func merge<T, U>(_ a: T, _ b: U) -> String
    where T: CustomStringConvertible, U: CustomStringConvertible {
    return "\(a) va \(b)"
}

4. Xotira Boshqaruvi (ARC)

21. ARC qanday ishlaydi?

Javob: ARC (Automatic Reference Counting) — class obyektlariga nechta kuchli (strong) havola borligini hisoblaydi. Hisoblagich 0 ga tushganda obyektni xotiradan o'chiradi:

class Person { let name: String; init(name: String) { self.name = name } }

var ref1: Person? = Person(name: "Ali") // ARC count = 1
var ref2 = ref1                         // ARC count = 2
ref1 = nil                              // ARC count = 1
ref2 = nil                              // ARC count = 0 → xotiradan o'chirildi ✅

22. Strong Reference Cycle nima?

Javob: Ikki class bir-birini kuchli ushlab qolsa, ARC ularni hech qachon o'chira olmaydi:

class Person {
    var pet: Dog?
}
class Dog {
    var owner: Person?  // ❌ Strong — Retain Cycle!
}

let ali = Person()
let rex = Dog()
ali.pet = rex   // Person → Dog (strong)
rex.owner = ali // Dog → Person (strong) — CYCLE!
// Hech biri xotiradan o'chmas!

23. weak va unowned farqi?

Javob:

  • weak — Optional bo'ladi. Obyekt o'chsa — nil qilinadi. Eng xavfsiz.
  • unowned — Optional emas. Obyekt o'chsa — crash. Faqat obyekt doim yashashiga 100% ishonchingiz bo'lganda.
class Dog {
    weak var owner: Person?  // ✅ Cycle buzildi
}

24. deinit nima?

Javob: Class obyekti xotiradan o'chirilish arafasida avtomatik chaqiriladigan metod:

class FileHandler {
    init() { print("Fayl ochildi") }
    deinit { print("Fayl yopildi — xotira tozalandi") }
}

25. Closure'larda Memory Leak qanday yuz beradi?

Javob: Closure self'ni strong ushlaydi, self esa closure'ni o'zida saqlaydi:

class ViewModel {
    var onComplete: (() -> Void)?
    
    func start() {
        onComplete = {
            self.doSomething() // ❌ self ni strong ushlab qoldi — CYCLE!
        }
        
        onComplete = { [weak self] in
            self?.doSomething() // ✅ weak — cycle yo'q
        }
    }
}

5. Error Handling va Pattern Matching

26. Swift'da xatolarni boshqarish (throws, do-catch)?

Javob:

enum LoginError: Error {
    case invalidEmail
    case wrongPassword
    case networkFailed(String)
}

func login(email: String, password: String) throws -> User {
    guard email.contains("@") else { throw LoginError.invalidEmail }
    guard password.count >= 8 else { throw LoginError.wrongPassword }
    return User(email: email)
}

// Chaqirish
do {
    let user = try login(email: "test@mail.com", password: "12345678")
    print("Kirdi: \(user.email)")
} catch LoginError.invalidEmail {
    print("Email noto'g'ri")
} catch LoginError.wrongPassword {
    print("Parol noto'g'ri")
} catch {
    print("Kutilmagan xato: \(error)")
}

27. try, try?, try! farqi?

Javob:

  • try — do-catch blokida ishlatiladi. Xato ushlanadi.
  • try? — xato bo'lsa nil qaytaradi (Optional).
  • try! — xato bo'lsa crash. Ishonchingiz komil bo'lgandagina.

28. Result<Success, Failure> turi?

Javob: Muvaffaqiyat yoki xatoni aniq ifodalovchi enum:

func fetchData() -> Result<[Post], NetworkError> {
    // ...
    return .success(posts)
    // yoki
    return .failure(.serverError)
}

switch fetchData() {
case .success(let posts): print("Postlar: \(posts.count)")
case .failure(let error): print("Xato: \(error)")
}

29. Pattern Matching (switch, if case)?

Javob:

let value: Any = 42

switch value {
case let x as Int where x > 0:
    print("Musbat son: \(x)")
case let s as String:
    print("Matn: \(s)")
case is Double:
    print("Bu kasr son")
default:
    print("Noma'lum")
}

// if case bilan
if case .success(let data) = result {
    print("Ma'lumot: \(data)")
}

30. guard va if farqi?

Javob:

  • guard — shart bajarilmasa funksiyadan chiqadi (early exit). O'zgaruvchi tashqarida ishlaydi.
  • if — shart bajarilsa blok ichida ishlaydi. O'zgaruvchi faqat qavs ichida.
// guard — toza va tekis kod
func processUser(name: String?) {
    guard let name = name else { return }
    print(name) // ← guard'dan tashqarida ham ishlaydi
}

// if — piramida hosil bo'ladi
func processUser2(name: String?) {
    if let name = name {
        print(name) // ← faqat qavs ichida ishlaydi
    }
}

6. Collections va Higher-Order Functions

31. Array, Set, Dictionary farqi?

Javob:

CollectionTartibDublikatQidirish tezligi
Array✅ Bor✅ MumkinO(n) — sekin
Set❌ Yo'q❌ Mumkin emasO(1) — tez
Dictionary❌ Yo'qKalit: ❌O(1) — tez

32. map, filter, reduce, compactMap, flatMap?

Javob:

let numbers = [1, 2, 3, 4, 5]

// map — har birini o'zgartirish
numbers.map { $0 * 2 }  // [2, 4, 6, 8, 10]

// filter — shartga mos keladigan
numbers.filter { $0 > 3 }  // [4, 5]

// reduce — yig'indi/jamlab bitta qiymat
numbers.reduce(0, +)  // 15

// compactMap — nil larni olib tashlash
["1", "abc", "3"].compactMap { Int($0) }  // [1, 3]

// flatMap — ichma-ich massivlarni tekislash
[[1, 2], [3, 4]].flatMap { $0 }  // [1, 2, 3, 4]

33. forEach va for-in farqi?

Javob: for-in — break va continue ishlatish mumkin. forEach — closure asosida bo'lgani uchun ularni ishlatib bo'lmaydi (faqat return butun tsiklni emas, faqat joriy iteratsiyani o'tkazib yuboradi).

34. Hashable protokoli nega kerak?

Javob: Set va Dictionary kalitlari uchun zarur. Hashable turga unikal butun son (hash value) beradi. Swift strukt'lardagi barcha property'lar Hashable bo'lsa, avtomatik conform qilinadi.

35. Sequence va Collection farqi?

Javob:

  • Sequence — elementlarni birma-bir olish (for-in bilan).
  • Collection — Sequence + indeks bilan to'g'ridan-to'g'ri kirish (array[2]), count, isEmpty.

7. Access Control va Modullar

36. Access Control darajalari?

Javob:

DarajaKo'rinish sohasi
openHamma joyda + subclass + override
publicHamma joyda + subclass (override ❌)
internal (default)Faqat modul ichida
fileprivateFaqat o'sha fayl ichida
privateFaqat o'sha qavs (scope) ichida

37. final kalit so'zi nima qiladi?

Javob: Class yoki metodini merosdan to'sadi. Bu Static Dispatch ga olib keladi — kompilyator aniq qaysi metodni chaqirishni bilgani uchun tezroq ishlaydi:

final class NetworkManager {
    // Bu class'dan meros olish MUMKIN EMAS
}

38. @frozen enum nima?

Javob: Kelajakda yangi case qo'shilmasligini kafolatlaydi (ABI stability uchun). Bu kompilyatorga optimallashtirish imkonini beradi.


8. Ilg'or Xususiyatlar (Advanced)

39. Property Wrappers nima?

Javob: Property'ga maxsus logika (getter/setter) qo'shish:

@propertyWrapper
struct Clamped {
    var wrappedValue: Int {
        didSet { wrappedValue = min(max(wrappedValue, range.lowerBound), range.upperBound) }
    }
    let range: ClosedRange<Int>
    
    init(wrappedValue: Int, _ range: ClosedRange<Int>) {
        self.range = range
        self.wrappedValue = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }
}

struct Player {
    @Clamped(0...100) var health = 100
}

var player = Player()
player.health = 150
print(player.health) // 100 — avtomatik chegaralandi

40. @autoclosure nima?

Javob: Ifodani avtomatik closure'ga o'rab beradi:

func assert(_ condition: @autoclosure () -> Bool, _ message: String) {
    if !condition() { print("XATO: \(message)") }
}

assert(2 + 2 == 5, "Matematika buzildi") // { 2 + 2 == 5 } — avtomatik closure

41. inout parametr nima?

Javob: Funksiya ichida tashqi o'zgaruvchini o'zgartirish:

func double(_ value: inout Int) {
    value *= 2
}

var number = 5
double(&number)
print(number) // 10

42. defer bloki?

Javob: Funksiya tugashidan oldin albatta bajariladigan kod (hatto xato bo'lsa ham):

func readFile() throws {
    let file = openFile()
    defer { closeFile(file) } // ← doim bajariladi
    
    let data = try file.read()
    process(data)
    // Bu yerda error bo'lsa ham closeFile() bajariladi
}

43. lazy property?

Javob: Faqat birinchi marta chaqirilganda hisoblanadi:

class DataManager {
    lazy var database: Database = {
        print("Ma'lumotlar bazasi yaratildi")
        return Database()
    }()
}

let dm = DataManager() // database hali yaratilmadi
dm.database.query()    // Endi yaratildi!

44. KeyPath nima?

Javob: Property'ga "yo'l" sifatida murojaat qilish:

struct User { let name: String; let age: Int }

let users = [User(name: "Ali", age: 25), User(name: "Vali", age: 30)]

let names = users.map(\.name)  // ["Ali", "Vali"] — KeyPath ishlatildi
let ages = users.map(\.age)    // [25, 30]

45. some va any (Opaque vs Existential)?

Javob:

  • some — kompilyatsiya vaqtida aniq bir tur (Static Dispatch, tezroq).
  • any — runtime'da istalgan mos tur (Dynamic Dispatch, moslashuvchan).
func makeShape() -> some Shape { Circle() }  // Tez
func processShape(_ shape: any Shape) { }    // Moslashuvchan

9. Concurrency (Bir vaqtdalik)

46. async/await nima?

Javob: Swift 5.5 da kiritilgan asinxron dasturlash tizimi:

func fetchUser() async throws -> User {
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Chaqirish
Task {
    do {
        let user = try await fetchUser()
        print(user.name)
    } catch {
        print(error)
    }
}

47. Actor nima?

Javob: Data Race'ning oldini oluvchi reference type. Uning ichiga bir vaqtda faqat bitta thread kira oladi:

actor BankAccount {
    var balance: Double = 0
    
    func deposit(_ amount: Double) {
        balance += amount  // Thread-safe!
    }
}

let account = BankAccount()
await account.deposit(100)  // await shart

48. Task va TaskGroup?

Javob:

  • Task { } — bitta asinxron ish boshlash.
  • TaskGroup — bir nechta parallel ishlarni guruhlash va hammasini kutish.

49. Sendable protokoli?

Javob: Thread'lar o'rtasida xavfsiz o'tkazish mumkinligini bildiradi. Value types avtomatik Sendable. Class'lar faqat immutable bo'lsa yoki @unchecked Sendable bo'lsa mos keladi.

50. MainActor nima?

Javob: Funksiya yoki class faqat Main Thread'da ishlashini kafolatlovchi global actor:

@MainActor
class ViewModel: ObservableObject {
    @Published var title = "" // UI property — faqat Main Thread
    
    func updateTitle() {
        title = "Yangilandi" // Xavfsiz — MainActor kafolatlaydi
    }
}

Yakuniy Maslahat:

Swift tili bo'yicha savollarga javob berishda "qanday ishlaydi" bilan birga "nima uchun shunday qilingan" (design decision) haqida ham gapiring. Bu sizning chuqur tushunchaga ega ekanligingizni ko'rsatadi. Muvaffaqiyat tilaymiz! 🦅

Markdown manba

iOS Lessons