Sobes.tech

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
27

Vorbește-mi despre utilizarea SwiftUI în proiect — care este politica, câte ecrane sunt scrise în SwiftUI

Senior
Salmon
27

Vorbește despre Property Wrapper-urile utile pe care le-ai folosit în proiect

Senior
Salmon
27

De ce ai ales un dicționar ca stocare în cache?

Middle+
RevolutRevolut
27

Vorbește-mi mai detaliat despre ultimul tău proiect — modulul de galerie foto de pe Avito, pentru care ai fost responsabil (închiriere pe termen scurt, formular de rezervare etc.)

Senior
Salmon
27

Cât de mult te ajută instrumentele de IA (Cursor, Proxyman etc.) să fii mai productiv la muncă?

Senior
Salmon
25

Cum înțelegi termenul de concurență structurată în Swift? Task.detached se potrivește acestei noțiuni?

Senior
Salmon
24

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
24

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
24

Explică diferența dintre un cache în memorie și un cache pe disc.

Middle+
RevolutRevolut
23

De ce ați creat metode separate load și getLastCities și ce ar trebui să se întâmple dacă getLastCities este apelat înainte ca datele să fie încărcate?

Senior
Uzum
23

// Scrie `data` într-un fișier numit `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) } // Șterge fișierul numit `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) } // Citește `Data` dintr-un fișier numit `file`. Dacă fișierul nu există, returnează `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
22

Cum ai prioritiza problemele identificate dacă proiectul trebuie să intre în producție într-o oră?

Senior
Uzum
20

De ce să folosiți o clasă finală în loc de o clasă pentru implementarea cache-ului?

Middle+
RevolutRevolut
16

enum HTTPMethod: String { case post = "POST" } enum Errors: Error { case invalidUrl case invalidQuery case invalidResponse case httpStatus(Int) } protocol MyDecoder { func decode<T: Decodable>(_: _ type: T.Type, from data: Data) throws -> T } final class NetworkService { private let session: URLSession private let encoder = JSONEncoder() private let decoder: MyDecoder init( session: URLSession = .shared, decoder: MyDecoder ) { self.session = session self.decoder = decoder } func request<Response: Decodable, Body: Encodable>( urlString: String, method: HTTPMethod, body: Body? = nil, headers: [String: String] = [:], query: [String: String] = [:] ) async throws -> Response { guard var components = URLComponents(string: urlString) else { throw Errors.invalidUrl } if !query.isEmpty { components.queryItems = query.map { URLQueryItem(name: $0.key, value: $0.value) } } guard let url = components.url else { throw Errors.invalidQuery } var request = URLRequest(url: url)

Middle+
СБЕРСБЕР
7

// Serviciul care trimite solicitări (get/post), url, formarea solicitării în funcție de semantică (decode/encode)

Middle+
СБЕРСБЕР
7
/206