Sobes.tech

final class ProfileViewModel1 { enum State { ... } var state: State = .idle let service: UserService init(service: UserService) { ... } func onBackPress() { // view deinit } func loadUser() { state = .loading Task { [weak self] guard let self else { return } do { let user = try await self.service.fetchUser() self.state = .loaded(user) } catch { self.state = .failed(error.localizedDescription) } } } }

Senior
Salmon
15

Были ли проблемы с конкурентностью (Sendable, unchecked Sendable, переход между акторами) в модулях, с которыми напрямую работал?

Senior
Salmon
15

Расскажи подробнее про свой последний проект — модуль фотогалереи в Авито, за который ты отвечал (краткосрочная аренда, форма бронирования и т.д.)

Senior
Salmon
15

Как ты понимаешь термин structured concurrency в Swift? Task.detached подходит под это понятие?

Senior
Salmon
14

Какая версия языка Swift используется на проекте — выше 6 или ниже?

Senior
Salmon
14

Насколько ИИ-инструменты (Cursor, Proxyman и т.д.) помогают тебе быть продуктивнее в работе?

Senior
Salmon
14

Briefly introduce yourself and describe your current work.

Middle+
RevolutRevolut
13

Расскажи про использование SwiftUI на проекте — какая политика, сколько экранов написано на SwiftUI

Senior
Salmon
13

import UIKit protocol CacheProtocol { associatedtype Value func setValue(_ value: Value?, forKey key: String) func getValue(forKey key: String) -> Value? func fetchValue(forKey key: String, completion: @escaping (Value?) -> Void) } final class Cache<T>: CacheProtocol { private var storage: [String: T] = [:] private let queue = DispatchQueue(label: "my.queue", attributes: .concurrent) func setValue(_ value: T?, forKey key: String) { queue.sync(flags: .barrier) { storage[key] = value } } func getValue(forKey key: String) -> T? { queue.sync { return storage[key] } } func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) { queue.async { let value = self.storage[key] completion(value) } } }

Middle+
RevolutRevolut
13

final class Cache<T>: CacheProtocol { func getValue(forKey key: String) -> T? { return storage[key] } func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) { let value = storage[key] completion(value) } } final class CacheTests: XCTestCase { override func setUp() { super.setUp() } func testSetAndGetValue() { let cache = Cache<String>() let key: String = "key" let value: String = "value" cache.setValue(value, forKey: key) XCTAssertEqual(cache.getValue(forKey: key), value) cache.setValue(nil, forKey: key) XCTAssertTrue(cache.getValue(forKey: key) == nil) } func testCompletion() { } } CacheTests.defaultTestSuite.run()

Middle+
RevolutRevolut
13

import UIKit protocol CacheProtocol { associatedtype Value func setValue(_ value: Value?, forKey key: String) func value(forKey key: String) -> Value? func fetchValue(forKey key: String, completion: @escaping (Value?) -> Void) }

Middle+
RevolutRevolut
12

What happens when nil is passed to set?

Middle+
RevolutRevolut
11

Why did you choose a dictionary as the cache storage?

Middle+
RevolutRevolut
11

// Writes `data` to a file named `file`. func writeData(_ data: Data, to file: String) { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) try? data.write(to: fileURL) } // Removes file named `file`. func remove(file: String) { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) try? FileManager.default.removeItem(at: fileURL) } // Reads `Data` from a file named `file`. If the file doesn't exists returns `nil`. func readData(from file: String) -> Data? { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) return try? Data(contentsOf: fileURL) } final class DiskCache<T>: CacheProtocol { func setValue(_ value: T?, forKey key: String) { } func getValue(forKey key: String) -> T? { } func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) { } }

Middle+
RevolutRevolut
11

protocol CacheProtocol { associatedtype Value func setValue(_ value: Value?, forKey key: String) func getValue(forKey key: String) -> Value? func fetchValue(forKey key: String, completion: @escaping (Value?) -> Void) } final class Cache<T>: CacheProtocol { private var storage: [String: T] = [:] func setValue(_ value: T?, forKey key: String) { storage[key] = value } func getValue(forKey key: String) -> T? { return storage[key] } func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) { let value = storage[key] completion(value) } } import XCTest final class CacheTests: XCTestCase { override func setUp() { super.setUp() } func testSetAndGetValue() { let cache = Cache<String>() let key: String = "key" let value: String = "value" cache.setValue(value, forKey: key) XCTAssertEqual(cache.getValue(forKey: key), value) cache.setValue(nil, forKey: key) XCTAssertTrue(cache.getValue(forKey: key) == nil) } } CacheTests.defaultTestSuite.run()

Middle+
RevolutRevolut
8

Explain the difference between an in-memory cache and an on-disk cache.

Middle+
RevolutRevolut
8

Why did the UI render correctly before adding an explicit main-thread dispatch?

Senior
Uzum
7

Why did you create separate load and getLastCities methods, and what should happen if getLastCities is called before data has been loaded?

Senior
Uzum
7

How would you prioritize the identified issues if the project must go to production in one hour?

Senior
Uzum
6

Why use final class instead of class for the cache implementation?

Middle+
RevolutRevolut
5
/206