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
letbilan 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 ishlaydiguard 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— faqatHashableprotokoliga 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-catchblokida ishlatiladi. Xato ushlanadi.try?— xato bo'lsanilqaytaradi (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:
| Collection | Tartib | Dublikat | Qidirish tezligi |
|---|---|---|---|
| Array | ✅ Bor | ✅ Mumkin | O(n) — sekin |
| Set | ❌ Yo'q | ❌ Mumkin emas | O(1) — tez |
| Dictionary | ❌ Yo'q | Kalit: ❌ | 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-inbilan).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:
| Daraja | Ko'rinish sohasi |
|---|---|
open | Hamma joyda + subclass + override |
public | Hamma joyda + subclass (override ❌) |
internal (default) | Faqat modul ichida |
fileprivate | Faqat o'sha fayl ichida |
private | Faqat 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! 🦅