Domande e risposte di colloquio per sviluppatore iOS senior

Milad Bonakdar
Autore
Preparati ai colloqui iOS senior con domande pratiche su Swift, SwiftUI, architettura, concorrenza, prestazioni, Core Data, offline sync e sicurezza.
Introduzione
Un colloquio iOS senior valuta se sai collegare Swift e i framework Apple a decisioni di produzione: architettura, gestione dello stato, concorrenza, prestazioni, persistenza, sicurezza e trade-off in un'app reale.
Usa questa guida per esercitarti con risposte che partono dalla decisione, spiegano il rischio da evitare e indicano lo strumento di Xcode o la tecnica di codice corretta. Una risposta senior deve essere utile anche in una code review, non solo teorica.
Swift avanzato e funzionalità del linguaggio (6 domande)
1. Spiega la gestione della memoria di Swift e ARC (Automatic Reference Counting).
Risposta: ARC gestisce automaticamente la memoria tracciando e gestendo i riferimenti alle istanze di classe.
- Come funziona: ogni istanza di classe ha un conteggio dei riferimenti. Quando il conteggio raggiunge lo zero, l'istanza viene deallocata.
- Riferimenti forti: predefinito. Aumenta il conteggio dei riferimenti.
- Riferimenti deboli: non aumentano il conteggio dei riferimenti. Diventano automaticamente
nilquando l'istanza viene deallocata. - Riferimenti non posseduti: non aumentano il conteggio dei riferimenti ma presuppongono che l'istanza esista sempre.
- Cicli di conservazione: si verificano quando due oggetti detengono forti riferimenti l'uno all'altro, impedendo la deallocazione.
Rarità: Molto comune Difficoltà: Difficile
2. Cosa sono i Generics in Swift e perché sono utili?
Risposta: I Generics ti consentono di scrivere funzioni e tipi flessibili e riutilizzabili che possono funzionare con qualsiasi tipo.
- Vantaggi: riutilizzabilità del codice, sicurezza del tipo, prestazioni (nessun overhead di runtime)
- Vincoli di tipo: limitano i tipi generici a protocolli o classi specifici
- Tipi associati: utilizzati nei protocolli per definire tipi di segnaposto
Rarità: Comune Difficoltà: Media
3. Spiega la differenza tra closure escaping e non-escaping.
Risposta:
- Non-escaping (predefinito): la closure viene eseguita prima che la funzione ritorni. Il compilatore può ottimizzare meglio.
- Escaping (
@escaping): la closure sopravvive alla funzione (memorizzata in una proprietà, chiamata in modo asincrono). Deve acquisire esplicitamenteself.
Rarità: Comune Difficoltà: Media
4. Qual è la differenza tra map, flatMap e compactMap?
Risposta: Queste sono funzioni di ordine superiore per trasformare le raccolte:
map: trasforma ogni elemento e restituisce un array di risultaticompactMap: comemapma filtra i valorinilflatMap: appiattisce gli array nidificati in un singolo array
Rarità: Comune Difficoltà: Facile
5. Spiega i Property Wrappers in Swift.
Risposta: I Property Wrappers aggiungono un livello di separazione tra il codice che gestisce come viene memorizzata una proprietà e il codice che definisce una proprietà.
- Esempi integrati:
@State,@Published,@AppStoragein SwiftUI - Wrapper personalizzati: definiscono comportamenti di proprietà riutilizzabili
Rarità: Media Difficoltà: Difficile
6. Cos'è il tipo Result e come viene utilizzato?
Risposta:
Result è un enum che rappresenta il successo o il fallimento, rendendo più esplicita la gestione degli errori.
- Definizione:
enum Result<Success, Failure: Error> - Vantaggi: gestione degli errori type-safe, contratti API più chiari, meglio delle funzioni di lancio per il codice asincrono
Rarità: Comune Difficoltà: Media
Modelli di architettura (5 domande)
7. Spiega il modello MVVM (Model-View-ViewModel).
Risposta: MVVM separa la logica dell'interfaccia utente dalla logica di business, rendendo il codice più testabile e manutenibile.
- Model: dati e logica di business
- View: UI (UIViewController, SwiftUI View)
- ViewModel: logica di presentazione, trasforma i dati del modello per la view
- Vantaggi: testabile (ViewModel non ha dipendenze UI), ViewModel riutilizzabili, chiara separazione delle preoccupazioni
Rarità: Molto comune Difficoltà: Media
8. Cos'è il modello Coordinator e perché usarlo?
Risposta: Il modello Coordinator separa la logica di navigazione dai view controller.
- Problema: view controller enormi con logica di navigazione mista alla logica dell'interfaccia utente
- Soluzione: i Coordinator gestiscono il flusso di navigazione
- Vantaggi: view controller riutilizzabili, navigazione testabile, flusso dell'app chiaro
Rarità: Media Difficoltà: Difficile
9. Spiega l'Dependency Injection in iOS.
Risposta: L'Dependency Injection è un modello di progettazione in cui le dipendenze vengono fornite a un oggetto anziché create internamente.
- Vantaggi: testabilità (iniezione di mock), flessibilità, basso accoppiamento
- Tipi:
- Constructor Injection: passa le dipendenze tramite l'inizializzatore (il più comune)
- Property Injection: imposta le dipendenze dopo l'inizializzazione
- Method Injection: passa le dipendenze come parametri del metodo
Rarità: Comune Difficoltà: Media
10. Cos'è il modello Repository?
Risposta: Il modello Repository astrae la logica di accesso ai dati, fornendo un'API pulita per le operazioni sui dati.
- Vantaggi: logica dei dati centralizzata, facile commutazione delle origini dati (API, database, cache), testabile
- Implementazione: il repository coordina tra più origini dati
Rarità: Media Difficoltà: Media
11. Spiega le differenze tra MVC, MVP e MVVM.
Risposta:
- MVC (Model-View-Controller):
- Modello predefinito di Apple
- Il controller media tra Model e View
- Problema: view controller enormi
- MVP (Model-View-Presenter):
- Il presenter gestisce tutta la logica dell'interfaccia utente
- La view è passiva (visualizza solo i dati)
- Migliore testabilità rispetto a MVC
- MVVM (Model-View-ViewModel):
- ViewModel espone flussi di dati
- La view si lega al ViewModel
- Ottimo per la programmazione reattiva (Combine, RxSwift)
Rarità: Comune Difficoltà: Difficile
Prestazioni e ottimizzazione (5 domande)
12. Come si ottimizzano le prestazioni di table view e collection view?
Risposta: Molteplici strategie migliorano le prestazioni di scorrimento:
- Riutilizzo delle celle: usa correttamente
dequeueReusableCell - Evita operazioni pesanti: non eseguire calcoli costosi in
cellForRowAt - Ottimizzazione delle immagini:
- Ridimensiona le immagini alla dimensione di visualizzazione
- Usa thread in background per l'elaborazione delle immagini
- Memorizza nella cache le immagini decodificate
- Prefetching: implementa
UITableViewDataSourcePrefetching - Caching dell'altezza: memorizza nella cache le altezze delle celle calcolate
- Evita la trasparenza: le view opache vengono renderizzate più velocemente
Rarità: Molto comune Difficoltà: Media
13. Spiega gli strumenti e come li usi per la profilazione delle prestazioni.
Risposta: Instruments è lo strumento di analisi delle prestazioni di Xcode.
- Strumenti comuni:
- Time Profiler: identifica il codice ad alta intensità di CPU
- Allocations: tiene traccia delle allocazioni di memoria e delle perdite
- Leaks: rileva le perdite di memoria
- Network: monitora l'attività di rete
- Energy Log: analizza l'utilizzo della batteria
- Flusso di lavoro:
- Profila l'app (Cmd+I)
- Scegli lo strumento
- Registra e interagisci con l'app
- Analizza l'albero delle chiamate e la timeline
- Identifica i colli di bottiglia
Rarità: Comune Difficoltà: Media
14. Come si rilevano e si correggono le perdite di memoria?
Risposta: Le perdite di memoria si verificano quando gli oggetti non vengono deallocati quando non sono più necessari.
- Cause comuni:
- Cicli di conservazione (cicli di riferimento forti)
- Closure che acquisiscono
selffortemente - Delegati non contrassegnati come
weak
- Rilevamento:
- Strumento Instruments Leaks
- Debugger del grafico di memoria in Xcode
- Osserva l'aumento dell'utilizzo della memoria
- Correzioni:
- Usa
weakounownedper i delegati - Usa
[weak self]o[unowned self]nelle closure - Interrompi i cicli di conservazione
- Usa
Rarità: Molto comune Difficoltà: Media
15. Quali tecniche usi per l'ottimizzazione dell'avvio dell'app?
Risposta: Un avvio dell'app più veloce migliora l'esperienza utente:
- Caricamento pigro: inizializza gli oggetti solo quando necessario
- Riduci il caricamento di Dylib: riduci al minimo le librerie dinamiche
- Ottimizza
application:didFinishLaunching:- Sposta il lavoro non critico in background
- Rimanda l'inizializzazione pesante
- Dimensione binaria: un binario più piccolo si carica più velocemente
- Evita operazioni pesanti: non bloccare il thread principale
- Misura: usa il modello App Launch di Instruments
Rarità: Comune Difficoltà: Media
16. Come gestisci la memorizzazione nella cache e il caricamento delle immagini?
Risposta: La gestione efficiente delle immagini è fondamentale per le prestazioni:
- Strategie:
- Cache di memoria: accesso rapido, dimensioni limitate
- Cache del disco: persistente, maggiore capacità
- Download: recupera dalla rete
- Librerie: SDWebImage, Kingfisher (gestiscono automaticamente la memorizzazione nella cache)
- Implementazione personalizzata:
Rarità: Comune Difficoltà: Difficile
Concorrenza e programmazione asincrona (4 domande)
17. Spiega async/await in Swift.
Risposta: Il moderno modello di concorrenza di Swift introdotto in Swift 5.5.
- Vantaggi: sintassi più pulita rispetto ai completion handler, gestione degli errori più semplice, sicurezza dei thread applicata dal compilatore
- Parole chiave:
async: contrassegna una funzione che può sospendereawait: contrassegna un punto di sospensioneTask: crea un nuovo contesto asincronoactor: tipo di riferimento thread-safe
Rarità: Molto comune Difficoltà: Difficile
18. Cosa sono gli Actor in Swift?
Risposta: Gli Actor sono tipi di riferimento che proteggono il loro stato mutabile dalle race condition.
- Sicurezza dei thread: solo un'attività può accedere allo stato mutabile dell'actor alla volta
- Sincronizzazione automatica: il compilatore applica l'accesso sicuro
- Main Actor: actor speciale per gli aggiornamenti dell'interfaccia utente
Rarità: Media Difficoltà: Difficile
19. Spiega il framework Combine.
Risposta: Combine è il framework di programmazione reattiva di Apple.
- Concetti fondamentali:
- Publisher: emette valori nel tempo
- Subscriber: riceve valori
- Operator: trasforma i valori
- Vantaggi: dichiarativo, componibile, operatori integrati
- Casi d'uso: networking, gestione dell'input utente, data binding
Rarità: Comune Difficoltà: Difficile
20. Qual è la differenza tra code seriali e concorrenti?
Risposta: Le code di dispatch eseguono attività in serie o in modo concorrente:
- Coda seriale: esegue un'attività alla volta in ordine FIFO. Le attività attendono il completamento dell'attività precedente.
- Coda concorrente: esegue più attività contemporaneamente. Le attività iniziano in ordine FIFO ma possono terminare in qualsiasi ordine.
- Coda principale: coda seriale speciale per gli aggiornamenti dell'interfaccia utente
Rarità: Comune Difficoltà: Media
Core Data e persistenza (3 domande)
21. Spiega l'architettura di Core Data e i suoi componenti principali.
Risposta: Core Data è il framework di Apple per grafi di oggetti e persistenza.
- NSManagedObjectModel: definizione dello schema (entità, attributi, relazioni)
- NSPersistentStoreCoordinator: coordina tra contesto e store
- NSManagedObjectContext: memoria di lavoro per gli oggetti (come un blocco note)
- NSPersistentStore: archiviazione effettiva (SQLite, binario, in memoria)
Rarità: Comune Difficoltà: Media
22. Come gestisci la concorrenza in Core Data?
Risposta: I contesti di Core Data non sono thread-safe. Usa i modelli di concorrenza corretti:
- Tipi di contesto:
- Contesto della coda principale: per le operazioni dell'interfaccia utente
- Contesto della coda privata: per le operazioni in background
- Best practice:
- Non passare mai oggetti gestiti tra thread
- Usa
performoperformAndWaitper le operazioni di contesto - Passa gli ID oggetto tra i contesti
Rarità: Media Difficoltà: Difficile
23. Cos'è NSFetchedResultsController e quando lo usi?
Risposta:
NSFetchedResultsController gestisce in modo efficiente i risultati di Core Data per table/collection view.
- Vantaggi:
- Tracciamento automatico delle modifiche
- Efficienza della memoria (batching)
- Gestione delle sezioni
- Aggiornamenti automatici dell'interfaccia utente
- Caso d'uso: visualizzazione di oggetti Core Data in table/collection view
Rarità: Media Difficoltà: Media
Progettazione del sistema e best practice (2 domande)
24. Come progetteresti un'app mobile offline-first?
Risposta: Le app offline-first funzionano senza Internet e si sincronizzano quando sono connesse.
- Architettura:
- Database locale come fonte di verità (Core Data, Realm)
- Livello di sincronizzazione per la riconciliazione con il server
- Strategia di risoluzione dei conflitti
- Strategie:
- Interfaccia utente ottimistica: mostra le modifiche immediatamente, sincronizza in background
- Accoda operazioni: archivia le richieste non riuscite, riprova quando sei online
- Timestamp/Versione: tiene traccia della freschezza dei dati
- Sfide:
- Risoluzione dei conflitti (last-write-wins, merge, scelta dell'utente)
- Coerenza dei dati
- Limiti di archiviazione
Rarità: Media Difficoltà: Difficile
25. Quali sono le tue strategie per la sicurezza delle app in iOS?
Risposta: Molteplici livelli prote


