uz
Feedback

Firibgarlarga uchmang! Telemetrio bunday kanallarni topadi va belgilaydi 👉 Belgini ko‘rmoqchi bo‘lsangiz, obuna bo‘ling

Swift | Вопросы собесов

Swift | Вопросы собесов

Kanalga Telegram’da o‘tish

Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads

Ko'proq ko'rsatish
2 143
Obunachilar
-224 soatlar
-47 kun
-2330 kun
Postlar arxiv
🤔 В чём разница между Int и UInt? - Int — это знаковое целое число, может быть как положительным, так и отрицательным. - UInt — беззнаковое, только положительные значения (включая 0). Использовать UInt нужно аккуратно: операции с Int и UInt напрямую не работают — нужно приводить типы. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Какие объекты участвуют в зависимостях? В зависимости от контекста, под "объектами, участвующими в зависимостях" можно понимать различные концепции. В программировании под зависимостями чаще всего подразумеваются связи между объектами или модулями, где один объект зависит от другого для выполнения своих функций. 🚩Объект-зависимый и объект-зависимость Когда один объект (например, ViewController) зависит от другого (NetworkManager), первый становится клиентом, а второй – зависимостью.
class NetworkManager {
    func fetchData() {
        print("Данные загружены")
    }
}

class ViewController {
    let networkManager: NetworkManager
    
    init(networkManager: NetworkManager) {
        self.networkManager = networkManager
    }
    
    func loadData() {
        networkManager.fetchData()
    }
}
🚩Протоколы как способ ослабления зависимостей Жесткие зависимости можно ослабить, используя протоколы.
protocol NetworkService {
    func fetchData()
}

class NetworkManager: NetworkService {
    func fetchData() {
        print("Данные загружены")
    }
}

class ViewController {
    let networkService: NetworkService
    
    init(networkService: NetworkService) {
        self.networkService = networkService
    }
    
    func loadData() {
        networkService.fetchData()
    }
}
🚩Зависимости в архитектурах (MVVM, VIPER, DI) В MVVM зависимость между ViewController и ViewModel. В VIPER модули зависят друг от друга, но слабо связаны через протоколы. В DI (Dependency Injection) зависимости передаются снаружи, что повышает тестируемость и гибкость. 🚩Менеджеры зависимостей Чтобы управлять внешними зависимостями (библиотеками), используются Swift Package Manager (SPM) CocoaPods Carthage Ставь 👍 и забирай 📚 Базу знаний

🤔 Что такое `unowned`? Это тип слабой ссылки в Swift, которая не увеличивает счётчик ссылок объекта. 1. В отличие от weak, unowned предполагает, что объект всегда существует. 2. Используется для предотвращения циклов удержания, но может привести к крашу, если объект освобождён. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Какие есть варианты обезопасить работу с историей images? Обеспечение безопасности работы с историей изображений в iOS-приложениях может включать несколько уровней защиты: 🟠Контроль доступа к изображениям - Используйте Privacy Settings (NSPhotoLibraryUsageDescription, NSCameraUsageDescription) для контроля доступа к фотоальбому. - Для ограниченного доступа в iOS 14+ используйте PHPickerViewController.
let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
if status == .authorized {
    // Доступ есть
} else {
    // Запросить разрешение
    PHPhotoLibrary.requestAuthorization { newStatus in
        if newStatus == .authorized {
            print("Доступ получен")
        }
    }
}
🟠Шифрование изображений - Если изображения сохраняются локально, используйте AES-шифрование. - Можно хранить ключ в Keychain или использовать Secure Enclave.
import CommonCrypto

func encryptImage(data: Data, key: Data) -> Data? {
    var buffer = Data(count: data.count + kCCBlockSizeAES128)
    var numBytesEncrypted: size_t = 0

    let status = CCCrypt(
        CCOperation(kCCEncrypt), CCAlgorithm(kCCAlgorithmAES),
        CCOptions(kCCOptionPKCS7Padding), key.bytes, key.count,
        nil, data.bytes, data.count, &buffer, buffer.count, &numBytesEncrypted
    )

    return status == kCCSuccess ? buffer.prefix(numBytesEncrypted) : nil
}
🟠Безопасное хранение изображений Core Data с Encrypted Store – можно использовать зашифрованные базы данных, такие как SQLCipher. FileManager + Data Protection – файлы можно хранить в Application Support с флагом .completeFileProtection. Keychain – если нужно хранить ссылки на изображения или ключи.
let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("secure_image.jpg")
try? imageData.write(to: fileURL, options: .completeFileProtection)
🟠Ограничение кеширования изображений - Если изображение чувствительное, отключите кеширование в URLSession:
let config = URLSessionConfiguration.default
config.urlCache = nil  // Отключаем кеш
let session = URLSession(configuration: config)
🟠Защита от утечек в памяти - Убедитесь, что ссылки на изображения не создают retain cycle. - Используйте weak ссылки в кэше изображений.
class ImageCache {
    private let cache = NSCache<NSString, UIImage>()
    
    func store(image: UIImage, forKey key: String) {
        cache.setObject(image, forKey: key as NSString)
    }
    
    func retrieve(forKey key: String) -> UIImage? {
        return cache.object(forKey: key as NSString)
    }
}
🟠Безопасная загрузка изображений (защита от MITM) - Используйте HTTPS вместо HTTP. - Включите App Transport Security (ATS) в Info.plist. - Верифицируйте SSL-сертификаты при загрузке.
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    if let serverTrust = challenge.protectionSpace.serverTrust {
        let credential = URLCredential(trust: serverTrust)
        completionHandler(.useCredential, credential)
    } else {
        completionHandler(.cancelAuthenticationChallenge, nil)
    }
}
Ставь 👍 и забирай 📚 Базу знаний

🔥 Скрытые вакансии с удаленной работой для iOS разработчика, которые нигде больше не публикуются. Напрямую от компаний, с ко
🔥 Скрытые вакансии с удаленной работой для iOS разработчика, которые нигде больше не публикуются. Напрямую от компаний, с контактами рекрутеров. 🔹 iOS Jobs | Вакансии 🔹 Flutter Dart Jobs | Вакансии 🔹 Android Jobs | Вакансии 🔸 Все каналы с вакансиями

🤔 Какой constraint на тип ключа накладывает Swift dictionary? Ключ должен соответствовать протоколу Hashable. Это необходимо, чтобы можно было быстро сравнивать и размещать ключи в хэш-таблице словаря. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Как бы реализовал словарь в Swift при помощи массива? В Swift словарь (Dictionary) представляет собой структуру данных, которая хранит пары ключ-значение и обеспечивает быстрый доступ к значениям по ключу (O(1) в среднем). Но если бы мы хотели реализовать словарь на основе массива, то пришлось бы использовать линейный поиск, что делает операции менее эффективными (O(n)). 🚩Реализация словаря через массив кортежей Один из простых способов создать словарь на базе массива — использовать массив кортежей (ключ, значение).
struct ArrayDictionary<Key: Equatable, Value> {
    private var items: [(Key, Value)] = []  // Храним пары ключ-значение

    // Получение значения по ключу
    func value(for key: Key) -> Value? {
        for (k, v) in items {
            if k == key {
                return v
            }
        }
        return nil
    }

    // Добавление или обновление значения
    mutating func insert(value: Value, for key: Key) {
        for i in 0..<items.count {
            if items[i].0 == key {
                items[i].1 = value  // Обновляем значение, если ключ уже есть
                return
            }
        }
        items.append((key, value))  // Добавляем новую пару
    }

    // Удаление элемента по ключу
    mutating func remove(for key: Key) {
        items.removeAll { $0.0 == key }
    }
}

// Пример использования
var myDict = ArrayDictionary<String, Int>()
myDict.insert(value: 42, for: "age")
myDict.insert(value: 30, for: "height")

print(myDict.value(for: "age")!)  // 42
myDict.remove(for: "age")
print(myDict.value(for: "age"))   // nil
🚩Оптимизация: Использование бинарного поиска Если мы отсортируем массив по ключам, можно использовать бинарный поиск (O(log n)) для ускорения поиска ключа.
struct SortedArrayDictionary<Key: Comparable, Value> {
    private var items: [(Key, Value)] = []

    // Бинарный поиск индекса ключа
    private func index(of key: Key) -> Int? {
        var left = 0
        var right = items.count - 1
        while left <= right {
            let mid = (left + right) / 2
            if items[mid].0 == key {
                return mid
            } else if items[mid].0 < key {
                left = mid + 1
            } else {
                right = mid - 1
            }
        }
        return nil
    }

    // Получение значения по ключу
    func value(for key: Key) -> Value? {
        if let index = index(of: key) {
            return items[index].1
        }
        return nil
    }

    // Вставка с сохранением сортировки
    mutating func insert(value: Value, for key: Key) {
        if let index = index(of: key) {
            items[index].1 = value
        } else {
            items.append((key, value))
            items.sort { $0.0 < $1.0 }  // Сортируем после вставки
        }
    }
}

// Использование
var sortedDict = SortedArrayDictionary<String, Int>()
sortedDict.insert(value: 50, for: "b")
sortedDict.insert(value: 20, for: "a")
sortedDict.insert(value: 70, for: "c")

print(sortedDict.value(for: "b")!)  // 50
Ставь 👍 и забирай 📚 Базу знаний

🤔 Какие типы очередей есть в многопоточности Swift? - Main queue — для UI и событий. - Serial queues — выполняют задачи последовательно. - Concurrent queues — позволяют выполнять несколько задач параллельно. - Global queues — предопределённые очереди системы с разными приоритетами (background, utility, userInitiated, userInteractive). Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Если обозначить внутри метода Synchronized , что будет монитору? Это высокоуровневый механизм синхронизации, который объединяет взаимное исключение (mutex) и условные переменные (condition variables) для управления доступом к объектам в многопоточной среде. 🚩Как работает 🟠Взаимное исключение (Mutual Exclusion) Только один поток может выполнить защищенный блок кода в любой момент времени. 🟠Условные переменные (Condition Variables) Позволяют потокам ожидать определенных условий, а другим потокам уведомлять их о наступлении этих условий. 🚩Примеры
class ThreadSafeClass {
    private var internalState = 0
    private let queue = DispatchQueue(label: "com.example.threadSafeQueue")
    
    func increment() {
        queue.sync {
            internalState += 1
        }
    }
    
    func getState() -> Int {
        return queue.sync {
            internalState
        }
    }
}
С NSLock
class ThreadSafeClass {
    private var internalState = 0
    private let lock = NSLock()
    
    func increment() {
        lock.lock()
        internalState += 1
        lock.unlock()
    }
    
    func getState() -> Int {
        lock.lock()
        let state = internalState
        lock.unlock()
        return state
    }
}
С objc_sync_enter и objc_sync_exit
class ThreadSafeClass: NSObject {
    private var internalState = 0
    
    func increment() {
        objc_sync_enter(self)
        internalState += 1
        objc_sync_exit(self)
    }
    
    func getState() -> Int {
        objc_sync_enter(self)
        let state = internalState
        objc_sync_exit(self)
        return state
    }
}
Ставь 👍 и забирай 📚 Базу знаний

🤔 За что отвечают Content Hugging Priority? Они определяют, насколько элемент предпочитает сохранять свой минимальный размер. Чем выше значение, тем меньше вероятность, что элемент растянется больше, чем необходимо его контенту. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Как сравниваются значения в dictionary? В Swift словарь (`Dictionary<Key, Value>`) – это неупорядоченная коллекция пар `ключ → значение`, где ключи уникальны. 🟠Сравнение двух словарей (`==`) Swift позволяет сравнивать два словаря по их ключам и значениям, если и ключи, и значения соответствуют протоколу Equatable.
let dict1 = ["name": "Alice", "age": "25"]
let dict2 = ["name": "Alice", "age": "25"]
let dict3 = ["name": "Bob", "age": "30"]

print(dict1 == dict2) // ✅ true (значения одинаковые)
print(dict1 == dict3) // ❌ false (разные значения)
Ошибка при сравнении Dictionary без Equatable Если значения не соответствуют `Equatable`, сравнение не сработает:
struct User {
    let name: String
}

let dict1 = ["user": User(name: "Alice")]
let dict2 = ["user": User(name: "Alice")]

// Ошибка: Type 'User' does not conform to protocol 'Equatable'
// print(dict1 == dict2)
Решение: Сделать User Equatable:
struct User: Equatable {
    let name: String
}

print(dict1 == dict2) // Теперь работает!
🟠Поиск и сравнение отдельных значений Можно сравнивать отдельные элементы по ключу.
let dict = ["name": "Alice", "age": "25"]

if dict["name"] == "Alice" {
    print("Имя совпадает") // ✅
}
🟠Сравнение по ключам (`keys`) и значениям (`values`) Можно сравнить только ключи или только значения.
let dict1 = ["name": "Alice", "age": "25"]
let dict2 = ["age": "30", "name": "Alice"]

print(dict1.keys == dict2.keys) // ✅ true (ключи одинаковые)
Сравнение значений
print(Set(dict1.values) == Set(dict2.values)) // ✅ true (если порядок неважен)
🟠Сравнение словарей с разными типами (`Any`) Если словарь хранит Any, то прямое сравнение не сработает, и нужно сравнивать элементы вручную.
let dict1: [String: Any] = ["name": "Alice", "age": 25]
let dict2: [String: Any] = ["name": "Alice", "age": 25]

// Функция сравнения словарей с `Any`
func areDictionariesEqual(_ dict1: [String: Any], _ dict2: [String: Any]) -> Bool {
    return NSDictionary(dictionary: dict1).isEqual(to: dict2)
}

print(areDictionariesEqual(dict1, dict2)) // ✅ true
Ставь 👍 и забирай 📚 Базу знаний

🚨 40 минут Пожизненный PRO по цене года закрывается прямо сейчас. Это последнее напоминание. 👉 https://easyoffer.ru/pro
🚨 40 минут Пожизненный PRO по цене года закрывается прямо сейчас. Это последнее напоминание. 👉 https://easyoffer.ru/pro

🎃 3 часа до полуночи... Ровно в 00:00 предложение исчезнет, как призрак на рассвете 👻 Последний шанс забрать PRO навсегда п
🎃 3 часа до полуночи... Ровно в 00:00 предложение исчезнет, как призрак на рассвете 👻 Последний шанс забрать PRO навсегда по цене одного года. Без продлений и без воскрешений. Если откладывал — не дай этой возможности стать твоим ночным кошмаром 🦇 👉 https://easyoffer.ru/pro

🤔 Что такое ARC? ARC (Automatic Reference Counting) — это механизм управления памятью в Swift, который автоматически освобождает память, когда объект больше не используется. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🕯 Страшилка на ночь Год спустя. Финальный этап собеседования. В комнате становится холодно. Интервьюер медленно наклоняется
🕯 Страшилка на ночь Год спустя. Финальный этап собеседования. В комнате становится холодно. Интервьюер медленно наклоняется и шепчет: «Почему вы ушли с прошлого места работы?» Ты открываешь easyoffer, а там… «Ваша подписка истекла» 💀 Чтобы эта история не стала твоей, забери пожизненный PRO по цене одного года. База собесов, эталонные ответы, автоотклики, тренажёры и всё, что появится дальше, остаются с тобой навсегда. ⏳ Осталось 7 часов. В полночь предложение исчезнет. 👉 https://easyoffer.ru/pro

🤔 Что такое runLoop? RunLoop — это фундаментальный механизм в iOS и macOS, который управляет циклом обработки событий в приложении. Он отслеживает и обрабатывает входящие события, такие как нажатия клавиш, касания экрана, таймеры и сетевые запросы, и поддерживает приложение в активном состоянии, пока оно не завершится. 🚩Основные аспекты `RunLoop` 🟠Цикл обработки событий RunLoop постоянно выполняет цикл, ожидая входящие события и обрабатывая их по мере поступления. Этот цикл состоит из нескольких этапов: ожидание события, обработка события и повтор цикла. 🟠Режимы (Modes) RunLoop может работать в разных режимах, которые определяют, какие источники событий будут отслеживаться и обрабатываться. Основные режимы включают default и tracking (для событий отслеживания, таких как прокрутка). В каждой итерации RunLoop обрабатывает события только для текущего режима.
RunLoop.current.run(mode: .default, before: Date.distantFuture)     
🟠Источники событий (Event Sources) RunLoop может отслеживать различные источники событий, такие как таймеры (Timer), порты (Port), ввод пользователей (такие как касания экрана и клики мыши), а также пользовательские источники (Input Source). 🟠Таймеры RunLoop может управлять таймерами, которые выполняют задачи через определенные интервалы времени.
     let timer = Timer(timeInterval: 1.0, repeats: true) { _ in
         print("Timer fired!")
     }
     RunLoop.current.add(timer, forMode: .default)
🟠Обработка событий RunLoop используется для обработки событий в основном потоке (main thread) приложения. Это особенно важно для поддержания отзывчивости пользовательского интерфейса, поскольку все взаимодействия с UI происходят в основном потоке. 🚩Пример использования `RunLoop`
import Foundation

class Example {
    var timer: Timer?

    func startRunLoop() {
        timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
        RunLoop.current.run()
    }

    @objc func timerFired() {
        print("Timer fired!")
    }
}

let example = Example()
example.startRunLoop()
Ставь 👍 и забирай 📚 Базу знаний

⏳ Сегодня последний день Платишь один раз и забираешь весь easyoffer навсегда, вместе со всеми будущими фичами проекта. Никак
⏳ Сегодня последний день Платишь один раз и забираешь весь easyoffer навсегда, вместе со всеми будущими фичами проекта. Никаких ежегодных продлений, только ты, твой оффер и мешок конфет 🍭 🎃 Завтра цена вернётся к обычной, и такого угощения уже не будет. 👉 https://easyoffer.ru/pro

🤔 Что известно про букву D в SOLID? Dependency Inversion Principle говорит, что модули высокого уровня не должны зависеть от модулей низкого уровня — они оба должны зависеть от абстракций. Это делается через протоколы и внедрение зависимостей. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Расскажи про букву D в solid Принцип инверсии зависимостей (Dependency Inversion Principle, DIP) гласит: Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций. 🚩Плохой пример (Нарушение DIP)
class MySQLDatabase {
    func fetchData() -> String {
        return "Данные из MySQL"
    }
}

class DataManager {
    let database = MySQLDatabase() // Прямая зависимость от MySQL

    func getData() -> String {
        return database.fetchData()
    }
}
🚩Хороший пример (Используем DIP) Вводим абстракцию (Протокол)
protocol Database {
    func fetchData() -> String
}
Реализуем конкретные базы данных
class MySQLDatabase: Database {
    func fetchData() -> String {
        return "Данные из MySQL"
    }
}

class PostgreSQLDatabase: Database {
    func fetchData() -> String {
        return "Данные из PostgreSQL"
    }
}
Используем абстракцию в DataManager
class DataManager {
    private let database: Database  // Зависимость от абстракции

    init(database: Database) {
        self.database = database
    }

    func getData() -> String {
        return database.fetchData()
    }
}
Использование
let mySQLDataManager = DataManager(database: MySQLDatabase())
print(mySQLDataManager.getData()) // "Данные из MySQL"

let postgreSQLDataManager = DataManager(database: PostgreSQLDatabase())
print(postgreSQLDataManager.getData()) // "Данные из PostgreSQL"
Ставь 👍 и забирай 📚 Базу знаний

Пожизненный PRO — по цене одного года. Покупаешь один раз — пользуешься всю жизнь: 👉 https://easyoffer.ru/pro 🚀 PRO-доступ
Пожизненный PRO — по цене одного года. Покупаешь один раз — пользуешься всю жизнь: 👉 https://easyoffer.ru/pro 🚀 PRO-доступ закроет 99% проблем на пути к офферу: 1. 1100+ записей реальных собеседований (включая топы: Сбер, Авито, Яндекс, WB, OZON, МТС). Видите всё изнутри: как спрашивают, как отвечают сильные кандидаты и на каких ошибках проваливаются 80%. 2. База live-coding задач и вопросов с реальных собесов — с уникальной системой вероятности их встречи. Готовитесь не вслепую, а точечно по темам, которые спрашивают чаще всего. 3. Эталонные ответы от Senior-разработчиков. Никакой воды и догадок — только чёткие структурированные решения, за которые дают «зелёный свет» к офферу. 4. Полный доступ ко всем грейдам и профессиям. Junior вы или Senior, тестировщик, разработчик или проджект — вы получаете ВСЕ материалы easyoffer без ограничений. Безлимитно, Все, Навсегда. 5. База 400+ тестовых заданий. Прокачивайте навыки на реальных задачах — тех самых, что дают перед собесом. 6. Автоотклики на hh — пока вы спите, резюме уходит рекрутерам автоматически. Экономия сотен часов ручного кликанья. 7. Аналитика ТОП-требований из вакансий. Парсим рынок и показываем, какие скиллы сейчас в цене. Апгрейдите резюме точечно и проходите ATS-фильтры (они отсеивают до 75% резюме ещё до рекрутера). 8. Генератор резюме и CV под каждую вакансию. Забудьте про «универсальное» резюме — нейросеть адаптирует ваш опыт под конкретную позицию за минуту и повышает шансы на приглашение в разы. 9. Тренажёры подготовки к собеседованию: «Реальное собеседование» — сценарий вопросов из настоящих интервью. «Проработка вопросов» — флеш-карточки по методике интервальных повторений (как Anki) 10. 🔥 Самое важное: все будущие фичи Вы платите один раз, а продукт растёт всю жизнь. Каждое обновление, каждый новый инструмент, каждая фича, которая появится за все годы проекта, автоматически падает вам в подписку без доплат. Вы фиксируете цену года, а получаете продукт, который через пару лет будет стоить в разы дороже ⭐️ Это уникальная акция пока сайт в режиме Beta. Успей ей воспользоваться ⏳ Завтра последний день. 👉 https://easyoffer.ru/pro