RUST Flashcards

costrutti particolari di rust (61 cards)

1
Q

Create an array

A

let arr: [i32; 5] = [1, 2, 3, 4, 5];

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Create a string

A

Only to read -> let s: &str;

To modify -> let s: String;
(String has string modification methods such as character insertion, string insertion, removal, clearing, contains, from str to String,…)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Multi dimensional array

A

let array: [[i64; 6] ;2];

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Pass reference read-only

A

fn(&var)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Pass reference to modify, without losing ownership

A

fn(&mut var)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Passing and returning arrays

A

let mut arr: [i32, 5];

fn(arr)

fn function (mut arr: [i32 ; 5]) -> [i32 ; 5]{
return arr;
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How to create new asyncronous channel?

A

let (tx, rx) = mpsc::channel()

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Cosa fa clone?

A

Per Collezioni clone copia effettivamente il dato.

Per smart pointers copia solo indirizzo allo stesso blocco di memoria.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

vettore indicizzato da cui rimuovere o aggiungere in testa

A

VedDeque<T>
pop back, pop front, push front, push back</T>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

mappa normale?

A

HashMap<K,V>.
get(), get_mut()
trait: Eq + std::hash::Hash

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

iterare lista

A

.iter o .iter_mut

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

condivisione di ownership?

A

Rc<t> signle thread, Arc<t> multithread</t></t>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

mutabilità interna?

A

RefCell<T> single thread (.borrow(), .borrow_mut()).</T>

Mutex<T> multithread (.lock())
oppure RxLock<T> se più accessi il lettura che scrittura (.read(), .write())</T></T>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Singola ownership?

A

Box<T> single thread</T>

per struct ricorsive o trait dinamici. Perché permette ad entrambi di non conoscere in compilazione la grandezza precisa di struct o trait, perché tanto in compilazione viene controllato lo stack e nello stack la box ha solo un puntatore di dimensione fissa.

A differenza di ownership normale che fa vivere i dati sullo stack, box li sposta sull’heap quindi è adatto per dati piu grandi.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Accedere a valore di Arc?

A

&*var

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

accedere a Result?

A

var.unwrap()

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Accedere a valore di MutexGuard?

A

*var

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Come gestire mutex?

A

prima di accederci fare sempre lock, poi fare drop esplicito nel caso di notify all.
Attenzione ad aggiornare la guard in caso di wait

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Impostando un problema a cosa stare attenti?

A

valore di ritorno delle funzioni

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Vedo vari riferimenti mutabili ed immutabili, a cosa devo stare attento?

A

che non possono esserci più riferimenti mutabili attivi insieme ad altri riferimenti immutabili attivi. in particolare scrittura->poi scrittura

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Quando serve la lifetime?

A

Quando una funzione prende più riferimenti e ne restituisce meno, dato che il compilatore non sa a quale dato il result farebbe riferimento.

oppure in una struct con riferimenti interni. (es &str)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Dopo che uso lifetime…?

A

attenzione che i parametri lifetime devono vivere >= del result

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Prima cosa a cui stare attenti quando viene trasferita ownership?

A

Se il tipo è primitivo, quindi copy. non trasferisce MAI ownership nel caso

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Closure differenza move o non move?

A

move trasferisce ownership sempre.

senza move trasferisce ownership solo se NECESSARIO. NECESSARIO SE: valore ritornato, dichiarazione, metodi consumatori come drop, into_…, iteratori che modificano, Option/Result.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Particolarità di Closure
Qualsiasi riferimento dopo fun() muore SUBITO. In closure: - riferimento muore solo dopo l'ultima chiamata alla closure. - se non consuma effettivamente il dato, allroa può essere richiamato più volte la closure prechè il dato rimane valido INTERNAMENTE - i dati usati da closure non sono soggetti a cambiamenti DOPO la definizione della closure.
26
Come creare threads?
Thread::spawn. Possibile condividere dati attraverso Fun() o Closure() solo se si trasferisce ownership, alternativamente da usare static. Thread::scope. Possibile condividere dati & e &mut anche senza trasferire ownership.
27
Cosa succede se Thread spawn usa dati senza condividerne ownership?
errore di data race. dovrebbe essere infatti usato per thread autonomi, a differenza di thread scope
28
Errori più comuni nell'uso di threads?
wait invece di wait_while. cicli infiniti senza condizioni di uscita.
29
trait deref?
30
trait copy?
31
trait send?
Serve per trasferire ownership di un dato tra thread. Serve a collezioni single thread. unsafe impl Send for s {}
32
trait sync?
Serve per permettere la lettura di un dato tra thread. Serve a collezioni single thread. unsafe impl Sync for s {}
33
trait iterator?
34
trait drop?
35
lunghezza di Arc,Rc?
1 word su stack: puntatore che punta a control block in heap in heap: 1 word di contatore strong + 1 word di contatore weak + dimensione dato puntato
36
Lunghezza Vec< T>
in stack: 1 word di puntatore ai dati + 1 word lunghezza vec + 1 word capacity in heap: lunghezza dati puntati
37
Lunghezza fat pointer? e chi sono fat pointer?
fat pointer sono Slices di array, Slices di strings o Trait object dinamici (Box, dyn Trait) in stack: 1 word puntatore a dati + (1 word di vtable per i trait OPPURE 1 word di lunghezza per i Slice) in heap o stack: dimensione dati puntati
38
Pattern fan out fan in
coppia di canali, uno invia dati ai worker, l'altro riceve output. tutti i thread fanno lo stesso lavoro. 1 producer ed 1 un consumer finale.
39
Pattern pipeline?
fasi separate collegate da canali. 1 producer ed 1 consumer
40
Pattern producer-consumer?
un solo canale che connette più producer o più consumer. Gestisce turno in base a chi arriva prima
41
thread pool e barrier?
thread pool crea un gruppo di n thread lavoratori, è come spawnarne tanti singolarmente, ma è più adatto thread pool se si parla di task veloci dato che i task vengono messi in coda ed i thread restano in vita pescando i task da fare dalla coda. a differenza di thread spawn che crea e distrugge thread ogni volta. thread pool ha un solo sender ed n receiver clonati Barrier sincronizza i thread, tutti aspettano al .wait()
42
In canali sincroni o asincroni a cosa devo stare attento se si fa drop di un receiver?
Devo eliminare il corrispettivo Sender con remove() o retain()
43
Binaryheap?
Albero binario che ha come elemento al top l'elemento massimo. .push(), .peek() e .pop(). Adatto a Scheduling. + T: Ord
44
Cos'è Scheduling?
è un pattern di alto livello come faninfanout, pipeline e producer-consumer. Scheduler serve a gestire come eseguire vari thread, assegnando ad ognuno una priorità. per questo problema è adatto usare una BinaryHeap
45
Come capire quando è da fare il thread pool?
type Job = Box;
46
come testare?
#[cfg(test)] mod tests {...} e funzione asser_eq!
47
monorfizzazione?
È il processo in cui il compilatore sostituisce i parametri generici (T) con tipi concreti (i32, String, ecc.) e genera versioni specifiche del codice per ogni tipo usato. Passaggi: Type checking sui generici Rust controlla il codice della funzione generica una volta sola, senza sapere ancora i tipi reali. Sostituzione dei tipi nei punti di uso Quando chiami la funzione con un tipo specifico (i32, String, ...), Rust sostituisce T con il tipo reale. Generazione MIR specializzato Il compilatore crea una versione ottimizzata (Mid-level IR) per ogni tipo usato. LLVM IR: traduzione del MIR in codice macchina ottimizzato TRADEOFF: c'è il contro che è possibile che la funzione può essere usata con molti tipi diversi, creando quindi un lungo codice binario. MA comunque la performance rimane ottima, essendo che è zero-cost abstraction.
48
Definizione V-Table?
è una tabella usata per supportare trait dinamici. c'è una vtable per ogni tipo di dato **concreto**. Contiene: - Puntatori alle funzioni implementate dal tipo per quel trait - Metadati fissi: size_of, align_of, drop
49
Cosa sono i metadati?
In Rust i metadati sono informazioni addizionali necessarie per gestire tipi non "Sized" (cioè di cui non si conosce a compile-time la dimensione esatta), come ad esempio i due tipi di fat pointer. ad esempio: len,vtable
50
cosa cambia da generics a dyn traits?
Generici (fn f(…)) → T è noto a compile-time, il compilatore genera (monomorfizza) una versione di f per ogni T. dyn Trait → il tipo concreto non è noto a compile-time: &dyn Trait è un fat pointer contenente solo un puntatore ai dati e uno alla vtable. Serve ad esempio per collezioni eterogenee.
51
cos'è dispatch statico o dinamico?
Static dispatch: Usato con i generics (W: Trait) Il compilatore genera una funzione specifica per ogni tipo (monomorfizzazione) Le chiamate sono dirette → no indirection inlining possibile → massimo delle performance Dynamic dispatch: Usato con dyn Trait Il puntatore è un fat pointer con: dati + vtable Le chiamate vanno via vtable → indirection, no inlining → leggero overhead Inlining: sostituire il corpo della funzione nel chiamante, evita salto di funzione Indirection: accedere a una funzione o dato passando da un puntatore (es. vtable)
52
cos'è zero cost abstraction in rust?
Rust garantisce che le sue astrazioni ad alto livello vengano compilate in codice efficiente quanto le implementazioni manuali equivalenti in C/C++. Meccanismi Chiave: - Inlining e LTO: Il compilatore incorpora aggressivamente le funzioni piccole direttamente nel codice chiamante. - Adattatori di iteratori: Le catene di operazioni come .map(..).filter(..).collect() vengono ottimizzate dal compilatore LLVM, vede tutta la catena e la fonde in un singolo ciclo - Pattern matching ed enum: Vengono tradotti in jump table o operazioni su bitmask senza allocazioni aggiuntive in memoria. quindi le enum vengono memorizzate solo come numeri in memoria, non come oggetti, in modo che il compilatore riesce in fretta a fare pattern matching.
53
Unsafe cos'è?
permette di fare un contratto tra programmatore e compilatore,per aggirare regole di borrow checker e permettere: unsafe in Rust serve per: - Dereferenziare puntatori raw (*const T, *mut T) - Accedere a unsafe functions o traits - Modificare stati condivisi senza sincronizzazione
54
box?
55
&T?
56
RefCell?
57
Cell?
58
Mutex?
59
enum?
60
Option?
61
Lifetime definizione?
è un etichetta che rappresenta l'intervallo di validità di un riferimento (&T o &mut T), cioè quanto a lungo può vivere quel riferimento senza diventare dangling (non valido). Serve ad assicurarsi che il risultato non viva più a lungo dei dati a cui punta.