71. Cosa succede se non sovrascriviamo il metodo toString() per Enum?
Diciamo che abbiamo la seguente enumerazione :public enum Role {
STUDENT,
TEACHER,
DIRECTOR,
SECURITY_GUARD;
}
Visualizziamo lo studente nella console chiamando toString() su di lui :
System.out.println(Role.STUDENT.toString());
Risultato nella console:
72. È possibile specificare un costruttore all'interno di un Enum?
Si certo. È attraverso il costruttore che vengono impostati i valori delle variabili enum interne. Ad esempio, aggiungiamo due campi all'enumerazione precedente - ageFrom e ageTo - per indicare la fascia di età per ciascun ruolo:public enum Role {
STUDENT(5,18),
TEACHER(20,60),
DIRECTOR(40,70),
SECURITY_GUARD(18,50);
int ageFrom;
int ageTo;
Role(int ageFrom, int ageTo) {
this.ageFrom = ageFrom;
this.ageTo = ageTo;
}
}
73. Qual è la differenza tra == e equals()?
Questa è una delle domande più comuni nelle interviste agli sviluppatori Java. Partiamo dal fatto che quando confrontiamo valori semplici ( int , char , double ...), lo facciamo utilizzando == , poiché le variabili contengono valori specifici e possiamo confrontarli. E le variabili primitive non sono oggetti a tutti gli effetti: non ereditano da Object e non hanno un metodo equals() . Quando parliamo di confrontare variabili che si riferiscono a oggetti, == confronterà solo il valore dei riferimenti, indipendentemente dal fatto che si riferiscano o meno allo stesso oggetto. E anche se un oggetto è identico a un altro, il confronto tramite == darà un risultato negativo ( false ), perché si tratta di un oggetto diverso. Come hai capito, il metodo equals() viene utilizzato per confrontare le variabili di riferimento . Questo è uno dei metodi standard della classe Object , necessario per un confronto completo degli oggetti. Ma è bene fare subito chiarezza: affinché questo metodo funzioni correttamente, è necessario ridefinirlo scrivendo esattamente come devono essere confrontati gli oggetti di questa classe. A meno che non si sovrascriva il metodo, per impostazione predefinita confronterà gli oggetti per == . In IntelliJ IDEA , puoi sovrascriverlo automaticamente (usando gli strumenti IDEA) -> alt + insert , nella finestra che appare, seleziona equals() e hashCode() -> seleziona quali campi di classe dovrebbero partecipare -> e voilà, implementazione automatica di i metodi sono completati. Ecco un esempio di come apparirebbe un metodo equals generato automaticamente per una semplice classe Cat con due campi: int age e String name :@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || this.getClass() != o.getClass()) return false;
final Cat cat = (Cat) o;
return this.age == cat.age &&
Objects.equals(this.name, cat.name);
}
Se parliamo della differenza tra == e equals per enums , non ce n’è molta. Dopotutto, enum memorizza costanti e, anche confrontando valori simili utilizzando == , riceveremo true , poiché i riferimenti saranno sempre agli stessi oggetti. Ebbene, quando si utilizza equals, lavoreremo anche correttamente sulla funzionalità, soprattutto se entri nel corpo del metodo equals per un enum , vedrai che nella classe Enum l'implementazione del metodo è la seguente: Cioè, all'interno - il buon vecchio paragone per riferimento! Per riassumere: per enum , il confronto sia con == che con equals è corretto.
74. Cosa fa il metodo ordinal() in Enum?
Quando chiamiamo il metodo int ordinal() su un elemento enum , otterremo il numero ordinale da zero di questo valore nella serie generale di enumerazioni. Usiamo questo metodo su un elemento dell'enumerazione precedente discussa : Ruolo :System.out.println(Role.DIRECTOR.ordinal());
Di conseguenza, la console visualizzerà:
75. È possibile utilizzare Enum con TreeSet o TreeMap in Java?
L'uso dei tipi enum in TreeSet e TreeMap è accettabile. E possiamo scrivere:TreeSet<Role> treeSet = new TreeSet<>();
treeSet.add(Role.SECURITY_GUARD);
treeSet.add(Role.DIRECTOR);
treeSet.add(Role.TEACHER);
treeSet.add(Role.STUDENT);
treeSet.forEach(System.out::println);
E la console mostrerà:
76. Come sono correlati i metodi ordinal() e compareTo() in Enum?
Come affermato in precedenza, ordinal() restituisce il numero ordinale di un valore in un elenco di enumerazione generale. Inoltre, nell'analisi della domanda precedente, hai visto che gli elementi delle enumerazioni, una volta, ad esempio, in un TreeSet (insieme ordinato) prendono l'ordine in cui sono dichiarati in enum . E come sappiamo, TreeSet e TreeMap ordinano gli elementi chiamando il loro metodo compareTo() dell'interfaccia Comparable . Da ciò possiamo supporre che la classe Enum implementi l' interfaccia Comparable , implementandola nel metodo compareTo() , all'interno del quale ordinal() viene utilizzato per impostare l'ordinamento. Entrando nella classe Enum , ne vediamo la conferma: E il corpo del metodo stesso: Il metodo ordinal() non viene chiamato qui. Viene invece utilizzata la variabile ordinale , ovvero il numero ordinale dell'elemento nell'enumerazione. Il metodo ordinal() stesso non è altro che un getter per la variabile ordinale .77. Scrivi un esempio EnumM
Nelle domande discusse sopra, ho già fornito esempi di enumerazioni e non vedo il motivo di duplicare il codice (ad esempio, la domanda numero 72 sul costruttore in enum).78. È possibile utilizzare Enum in un caso di switch?
È possibile e necessario! Ripensando alla mia pratica, noto che uno dei luoghi più comuni in cui utilizzare enum sono i costrutti logici come switch . In questo caso, puoi fornire tutte le possibili variazioni di case e, dopo aver scritto la logica per tutti i valori enum , l'utilizzo dell'operatore predefinito potrebbe non essere nemmeno necessario! Dopotutto, se utilizzi una String o un valore numerico, ad esempio, di tipo int , potresti ricevere un valore imprevisto, cosa che a sua volta è impossibile utilizzando un enum . Come sarebbe un interruttore per l'esempio discusso in precedenza:public void doSomething(Role role) {
switch (role) {
case STUDENT:
// некая логика для STUDENT
break;
case TEACHER:
// некая логика для TEACHER
break;
case DIRECTOR:
// некая логика для DIRECTOR
break;
case SECURITY_GUARD:
// некая логика для SECURITY_GUARD
break;
}
}
79. Come ottenere tutti i valori disponibili in un'istanza Enum?
Se è necessario ottenere tutte le istanze di un'enumerazione, esiste un metodo value() che restituisce un array di tutti i valori disponibili di una particolare enumerazione in ordine naturale (nell'ordine in cui sono stati specificati in enum ). Esempio:Role[] roles = Role.values();
for (Role role : roles) {
System.out.println(role);
}
La console visualizzerà il seguente output:
API di flusso
80.Che cos'è lo streaming in Java?
Java Stream è un modo relativamente nuovo di interagire con un flusso di dati, che a sua volta consente di elaborare dati di grandi dimensioni in modo più conveniente e compatto, nonché di parallelizzare l'elaborazione dei dati tra un certo numero di thread, il che può aumentare le prestazioni nell'utilizzo funzionalità. Questo argomento non può essere discusso più approfonditamente in poche parole, quindi lascerò qui un collegamento a un articolo che può aiutarti ad approfondire questo argomento.81. Quali sono le principali proprietà delle transazioni?
L'argomento si chiama Stream API, ma la domanda riguarda la transazione. Hmm... Per prima cosa, cerchiamo di capire cos'è una transazione. Una transazione è un gruppo di operazioni sequenziali del database che rappresenta un'unità logica di utilizzo dei dati. Una transazione può essere completata interamente e con successo, mantenendo l'integrità dei dati e indipendentemente da altre transazioni eseguite in parallelo, oppure non può essere completata affatto, nel qual caso non ha alcun effetto. Pertanto, le transazioni hanno quattro proprietà principali, chiamate in breve ACID . Vediamo come ogni lettera di questa abbreviazione sta per: A - Atomicità - atomicità - questa proprietà garantisce che nessuna transazione verrà parzialmente registrata nel sistema. Verranno eseguite tutte le sue operazioni secondarie oppure nessuna ( tutto o niente ). C - Coerenza - la coerenza è una proprietà che garantisce che ogni transazione andata a buon fine registri solo risultati validi. Cioè, questa è una garanzia che, in caso di transazione riuscita, tutte le regole e le restrizioni imposte dal sistema su dati specifici verranno rispettate, altrimenti la transazione non verrà completata e i dati nel sistema torneranno al loro stato precedente stato. I - Isolamento - l'isolamento è una proprietà che dice che durante l'esecuzione di una transazione, le transazioni parallele non dovrebbero influenzarne il risultato. Questa proprietà richiede molte risorse, quindi viene generalmente implementata in parte consentendo determinati livelli di isolamento che risolvono determinati problemi di isolamento. Ne discuteremo più in dettaglio nella prossima domanda. D - Durabilità - questa proprietà garantisce che se l'utente ha ricevuto conferma dal sistema che la transazione è stata completata, può essere sicuro che le modifiche apportate non verranno annullate a causa di qualche errore. Cioè, puoi essere sicuro che qualche tipo di guasto del sistema operativo non farà nulla ai tuoi dati se hai già ricevuto la conferma del completamento con successo della transazione.82. Quali sono i livelli di isolamento delle transazioni?
Come ho detto prima, fornire l'isolamento ACID è un processo che richiede molte risorse. Pertanto tale proprietà è parzialmente soddisfatta. Esistono diversi livelli di isolamento e quanto più alto è il livello, tanto maggiore è l’impatto sulla produttività. Prima di passare ai livelli di isolamento delle transazioni, dobbiamo esaminare i vari problemi di isolamento insufficiente delle transazioni :-
lettura fantasma - quando lo stesso campione (la stessa query) viene richiamato ripetutamente all'interno della stessa transazione, i dati ricevuti differiscono, il che si verifica a causa dell'inserimento di dati da parte di un'altra transazione;
-
lettura non ripetuta : quando lo stesso campione (la stessa query) viene richiamato ripetutamente all'interno della stessa transazione, i dati ricevuti differiscono, il che si verifica a causa di modifiche (aggiornamento) ed eliminazioni di dati da parte di un'altra transazione;
-
lettura sporca - il processo di lettura dei dati aggiunti o modificati da una transazione che successivamente non è stata confermata (ripristinata), ad es. lettura di dati non validi;
-
aggiornamento perso : quando diverse transazioni modificano gli stessi dati contemporaneamente, tutte le modifiche tranne l'ultima vengono perse (che ricorda il problema della "race condition" in un ambiente multi-thread).
Livello di isolamento | Lettura fantasma | Lettura non ripetitiva | Lettura sporca | Aggiornamento perso |
---|---|---|---|---|
SERIALIZZABILE | + | + | + | + |
LETTURA RIPETIBILE | - | + | + | + |
LEGGI IMPEGNO | - | - | + | + |
LEGGI SENZA IMPEGNO | - | - | - | + |
NESSUNO | - | - | - | - |
83. Qual è la differenza tra Statement e PreparedStatement?
E qui non c'è una transizione molto fluida verso le funzionalità della tecnologia JDBC . Quindi, per prima cosa, scopriamo cos'è effettivamente Statement . Questo è un oggetto utilizzato per generare query SQL. JDBC utilizza tre tipi : Statement , PreparedStatement e CallableStatement . Oggi non parleremo di CallableStatement : parliamo della differenza tra Statement e PreparedStatement .-
L'istruzione viene utilizzata per eseguire semplici query SQL senza parametri in entrata inseriti dinamicamente. PrepareStatement viene utilizzato con la possibilità di inserire dinamicamente parametri di input.
-
Per impostare i parametri in PreparedStatement, i parametri di input nella richiesta vengono scritti come punti interrogativi, per poi inserire qualche valore al loro posto utilizzando vari setter, come setDouble() , setFloat() , setInt() , setTime() .. .. Di conseguenza, non inserirai il tipo sbagliato di dati nella tua query.
-
PreparedStatement è "precompilato" e utilizza la memorizzazione nella cache, quindi la sua esecuzione può essere leggermente più veloce rispetto all'esecuzione di query da oggetti Statement . Di conseguenza, le query SQL eseguite frequentemente vengono scritte come oggetti PreparedStatement per migliorare le prestazioni .
-
Statement è vulnerabile alle SQL injection, mentre PreparedStatement le previene. Scopri di più sull'eliminazione delle SQL injection e altre best practice nella sicurezza Java in questo articolo .
GO TO FULL VERSION