Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar
translation

Questo è un post tradotto da IA.

제이온

[Effective Java] Item 1. Consider static factory methods instead of constructors

Seleziona la lingua

  • Italiano
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar

Testo riassunto dall'intelligenza artificiale durumis

  • I metodi di fabbrica statici sono un modo per creare istanze di una classe al posto dei costruttori, offrendo il vantaggio di poter denominare le istanze, migliorare le prestazioni memorizzando nella cache oggetti con un costo di creazione elevato e restituire, se necessario, oggetti di sottotipi diversi.
  • In particolare, prima di Java 8, non era possibile dichiarare metodi statici nelle interfacce, quindi era necessario creare una classe companion per definire i metodi di fabbrica statici. Dopo Java 8, è possibile aggiungere metodi statici direttamente alle interfacce, eliminando la necessità di definire una classe companion separata.
  • L'utilizzo di metodi di fabbrica statici può incoraggiare la composizione rispetto all'eredità, e il fatto che questo vincolo debba essere rispettato per creare tipi immutabili può essere un vantaggio. Tuttavia, a differenza dei costruttori, non sono esplicitamente visibili nella documentazione dell'API, quindi gli sviluppatori devono mitigare questo problema fornendo una buona documentazione dell'API e utilizzando nomi di metodi che seguono convenzioni ben consolidate.

Panoramica

Il modo tradizionale per ottenere un'istanza di una classe è tramite un costruttore pubblico.


public class Member {

    private String name;

    private int age;

    private String hobby;

    private MemberStatus memberStatus;

    public Member(String name, int age, String hobby, MemberStatus memberStatus) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        this.memberStatus = memberStatus;
    }
}

public enum MemberStatus {

    ADVANCED,
    INTERMEDIATE,
    BASIC;


Generalmente, un costruttore pubblico è sufficiente, ma a volte, fornendo un metodo statico di fabbrica (static factory method) oltre al costruttore, è più facile per l'utente creare un'istanza come previsto.


Un esempio tipico di metodo statico di fabbrica è il metodo valueOf() di Boolean.


public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;


Il metodo sopra accetta un valore di tipo primitivo boolean e restituisce un oggetto Boolean.


Vantaggi dei metodi statici di fabbrica

Può avere un nome.

I parametri passati al costruttore e il costruttore stesso non sono in grado di descrivere adeguatamente le caratteristiche dell'oggetto restituito. Ad esempio, è difficile capire da solo quale tipo di Member sia dalla classe Member di cui sopra, solo guardando il costruttore principale (nome, età, hobby, stato membro).


Inoltre, è possibile creare un solo costruttore per una singola firma, mentre i metodi statici di fabbrica possono avere un nome, quindi è possibile creare più metodi statici di fabbrica con la stessa firma per restituire istanze.


public class Member {

    private String name;

    private int age;

    private String hobby;

    private MemberStatus memberStatus;

    public Member(String name, int age, String hobby, MemberStatus memberStatus) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        this.memberStatus = memberStatus;
    }

    public static Member basicMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.BASIC);
    }

    public static Member intermediateMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.INTERMEDIATE);
    }

    public static Member advancedMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.ADVANCED);
    }


Come sopra, creare più metodi statici di fabbrica con la stessa firma anziché usare il costruttore per distinguere il MemberStatus, consente all'utente di creare un'istanza di Member con specifiche capacità senza confusione.

Guardando le librerie definite nel JDK, esiste un metodo statico di fabbrica, probablePrime(), in BigInteger.


public static BigInteger probablePrime(int bitLength, Random rnd) {
    if (bitLength < 2)
        throw new ArithmeticException("bitLength < 2");

    return (bitLength < SMALL_PRIME_THRESHOLD ?
            smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
            largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));


Comparando il costruttore generale di BigInteger con il metodo statico di fabbrica probablePrime(), quest'ultimo descrive meglio il fatto che restituisce un BigInteger che è un numero primo.


Non è necessario creare una nuova istanza ogni volta che viene chiamato.

public static Boolean valueOf(boolean b) {
    return (b ? Boolean.TRUE : Boolean.FALSE);


Si può vedere che il metodo valueOf() di Boolean mette in cache le istanze e le restituisce. Questa caratteristica può migliorare significativamente le prestazioni, soprattutto quando vengono richieste frequentemente oggetti con elevati costi di creazione, ed è possibile vederla come una tecnica simile aFlyweight Pattern.


Le classi che usano il metodo statico di fabbrica per restituire lo stesso oggetto alle richieste ripetute sono chiamate classi di controllo delle istanze perché possono controllare il ciclo di vita delle istanze. Controllando le istanze, è possibile creare una classe singleton o una classe non istanziabile. Inoltre, è possibile garantire che ci sia una sola istanza nelle classi di valori immutabili.

Il controllo delle istanze è alla base del modello Flyweight e i tipi enumerati garantiscono che venga creata solo una singola istanza.


Esempio

In Minecraft, è necessario piantare alberi. Se si crea un nuovo oggetto per ogni albero, è probabile che si verifichi un overflow di memoria.

Pertanto, come sopra, è possibile memorizzare gli oggetti albero rosso e albero verde e restituire solo la posizione. Ovviamente, poiché il colore può essere più di due colori, sarebbe più efficiente memorizzare gli alberi in base al colore in una struttura dati come Map.


public class Tree {

    // Un albero ha le seguenti 3 informazioni
    private String color;
    private int x;
    private int y;

    // Il costruttore è creato solo dal colore.
    public Tree(String color) {
        this.color = color;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    // Quando pianti un albero
    public void install(){
        System.out.println("x:"+x+" y:"+y+" posizione con un albero di colore "+color+"!");
    }
}

public class TreeFactory {
    // Gestisce gli alberi creati utilizzando la struttura dati HashMap.
    public static final Map treeMap = new HashMap<>();
    
   
    public static Tree getTree(String treeColor){
        // Controlla se c'è un albero del colore immesso nella mappa. Se esiste, fornisce quell'oggetto.
        Tree tree = (Tree)treeMap.get(treeColor); 

       // Se non c'è ancora un albero dello stesso colore nella mappa, crea un nuovo oggetto e forniscilo.
        if(tree == null){
            tree = new Tree(treeColor);
            treeMap.put(treeColor, tree);
            System.out.println("Nuovo oggetto creato");
        }

        return tree;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("Inserisci il colore desiderato :)");
        for(int i=0;i<10;i++){
            // Inserimento del colore dell'albero
            String input = scanner.nextLine();
            // Ricezione di un albero dalla fabbrica
            Tree tree = (Tree)TreeFactory.getTree(input);
            // Imposta x,y dell'albero e
            tree.setX((int) (Math.random()*100));
            tree.setY((int) (Math.random()*100));
            // Installa l'albero
            tree.install();
        }
    }


Differenza con il modello Singleton

Il modello Singleton consente di creare un solo albero nella classe albero. Pertanto, se si utilizza il modello Singleton, è necessario modificare il colore dell'unico oggetto creato. In altre parole, il modello Singleton consente di avere un solo oggetto indipendentemente dal tipo.


Casi d'uso

Il modello Flyweight viene utilizzato nel pool di costanti String di Java.


Può restituire un oggetto di un sottotipo del tipo di ritorno.

Se hai mai usato il metodo asList() della classe utility Arrays, puoi capire questo vantaggio.


public static  List asList(T... a) [
    return new ArrayList<>(a);


Restituisce un valore avvolto in ArrayList, che è un'implementazione di sottotipo di List, ma l'utente non ha bisogno di conoscere questa implementazione. Vale a dire, la flessibilità di poter scegliere la classe dell'oggetto restituito consente allo sviluppatore di restituire l'implementazione senza esporla, il che consente di mantenere l'API di dimensioni ridotte.


Storia dei metodi statici dell'interfaccia Java

Prima di Java 8, non era possibile dichiarare metodi statici nelle interfacce, quindi se fosse stato necessario un metodo statico che restituisse un'interfaccia denominata "Type", sarebbe stato necessario creare una classe associata non istanziabile denominata "Types" per definire il metodo al suo interno.


Un esempio tipico sono le 45 implementazioni di utilità fornite da JCF, la maggior parte delle quali vengono ottenute tramite metodi statici di fabbrica nella classe associata java.util.Collections. In particolare, alcune di queste implementazioni non sono pubbliche e possono essere istanziate solo tramite metodi statici di fabbrica (naturalmente, queste implementazioni non possono essere ereditate).


Inoltre, poiché non vengono esposte 45 implementazioni, l'API può essere molto più piccola.


// Esempio di interfaccia e classe associata


Tuttavia, a partire da Java 8, è possibile aggiungere metodi statici direttamente alle interfacce, quindi non è più necessario definire una classe associata separatamente.


È possibile restituire un oggetto di una classe diversa a seconda del parametro di input.

Oltre a restituire semplicemente un sottotipo, è possibile restituire un sottotipo diverso a seconda del valore del parametro. Ad esempio, se si desidera restituire un MemberStatus diverso a seconda del punteggio, è possibile creare un metodo statico di fabbrica come quello sottostante e inserire la logica di confronto al suo interno.


public enum MemberStatus {

    ADVANCED(80, 100),
    INTERMEDIATE(50, 79),
    BASIC(0, 49);

    private final int minScore;
    private final int maxScore;

    MemberStatus(int minScore, int maxScore) {
        this.minScore = minScore;
        this.maxScore = maxScore;
    }

    public static MemberStatus of(int score) {
        return Arrays.stream(values())
                .filter(decideMemberStatus(score))
                .findAny()
                .orElseThrow(() -> new NoSuchElementException("Non esiste un oggetto MemberStatus corrispondente."));
    }

    private static Predicate decideMemberStatus(int score) {
        return element -> element.minScore <= score && element.maxScore >= score;
    }
}

@DisplayName("MemberStatus Test")
class MemberStatusTest {

    @ParameterizedTest
    @CsvSource(value = {"0:BASIC", "30:BASIC", "50:INTERMEDIATE", "70:INTERMEDIATE", "80:ADVANCED", "100:ADVANCED"}, delimiter = ':')
    @DisplayName("Restituisce MemberStatus diverso a seconda del punteggio.")
    void of(int input, MemberStatus expected) {
        assertThat(MemberStatus.of(input)).isEqualTo(expected);
    }


La classe dell'oggetto da restituire non deve esistere al momento della scrittura del metodo statico di fabbrica.

Nella frase sopra,classe dell'oggettosi riferisce al file di classe che scriviamo.

Per inciso, Class si riferisce all'oggetto Class che l'oggetto ClassLoader alloca nell'area heap quando carica una classe. Questo oggetto Class contiene vari metadati della classe che abbiamo scritto.


package algorithm.dataStructure;

public abstract class StaticFactoryMethodType {

    public abstract void getName();

    public static StaticFactoryMethodType getNewInstance() {
        StaticFactoryMethodType temp = null;
        try {
            Class childClass = Class.forName("algorithm.dataStructure.StaticFactoryMethodTypeChild"); // Riflessione
            temp = (StaticFactoryMethodType) childClass.newInstance(); // Riflessione

        } catch (ClassNotFoundException e) {
           System.out.println("Classe non trovata.");
        } catch (InstantiationException  e) {
            System.out.println("Impossibile caricare in memoria.");
        } catch (IllegalAccessException  e) {
            System.out.println("Errore di accesso al file di classe.");
        }

        return temp;
    }


Nel codice precedente, puoi vedere che un oggetto Class viene creato in base al percorso dell'implementazione dell'interfaccia e la tecnica della riflessione viene utilizzata per inizializzare l'implementazione effettiva. In questo caso,al momento della scrittura del metodo statico di fabbrica, la classe StaticFactoryMethodTypeChild non deve esistere.


Se non esiste un'implementazione nel percorso algorithm.dataStructure.StaticFactoryMethodTypeChild al momento dell'utilizzo del metodo statico di fabbrica, si verificherà un errore, ma non ci saranno problemi al momento della scrittura del metodo statico di fabbrica, quindi è flessibile.


public interface Test {

    int sum(int a, int b);

    // Test è un'interfaccia e non ci sono problemi a scrivere il metodo statico di fabbrica anche se non ci sono implementazioni.
    static Test create() {
        return null;
    }
}

public class Main {

    public static void main(String[] args) {
        Test test = Test.create();
        System.out.println(test.sum(1, 2)); // Si verifica NPE
    }


È possibile ottenere la stessa flessibilità senza utilizzare la riflessione. Guardando il metodo statico di fabbrica create() di Test, non ci sono problemi a scriverlo anche se non ci sono implementazioni. Naturalmente, si verifica un NPE al momento dell'effettivo utilizzo, quindi è necessario restituire l'implementazione in un secondo momento.


Questa flessibilità è alla base della creazione di framework di provider di servizi, di cui JDBC è un esempio tipico. Il provider del framework di provider di servizi è l'implementazione del servizio e il framework controlla la fornitura di queste implementazioni al client, separando il client dall'implementazione (DIP).


  • Componenti del framework di provider di servizi
    • Interfaccia di servizio
      • Definisce il comportamento dell'implementazione.
      • JDBC Connection
    • API di registrazione del provider
      • Il provider registra l'implementazione.
      • JDBC DriverManager.registerDriver()
    • API di accesso al servizio
      • Utilizzato dal client per ottenere un'istanza del servizio, e se non sono specificate condizioni, restituisce l'implementazione predefinita o l'implementazione supportata in modo rotatorio.
      • Corrispondenza dei metodi statici di fabbrica
      • JDBC DriverManager.getConnection()
    • (Opzionale) Interfaccia di provider di servizi
      • Se questo non esiste, è necessario utilizzare la riflessione per istanziare ogni implementazione.
      • JDBC Driver


Il modello di framework di provider di servizi ha molte varianti, tra cui il modello Bridge, il framework di iniezione di dipendenze, ecc.


Tipico Esempio JDBC

Class.forName("oracle.jdbc.driver.OracleDriver"); 
Connection connection = null; 
connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORA92", "root", "root"); 


Generalmente, JDBC viene scritto come sopra. Tramite Class.forName(), viene registrato uno degli implementatori di Driver, OracleDriver, e tramite DriverManager.getConnection(), viene ottenuto uno degli implementatori di Connection, Connection per OracleDriver.


Qui, Connection è l'interfaccia di servizio, DriverManager.getConnection() è l'API di accesso al servizio e Driver è l'interfaccia di provider di servizi. Tuttavia, l'API di registrazione del provider, DriverManager.registerDriver(), non viene utilizzata. Tuttavia, è possibile registrare OracleDriver, che è un'implementazione di Driver, usando solo Class.forName(). Come è possibile?


Meccanismo di funzionamento di Class.forName()

Questo metodo accetta il nome del file di classe fisico come argomento e richiede alla JVM di caricare la classe. Il caricatore di classi memorizza i metadati della classe nell'area metodo e alloca anche un oggetto Class nell'area heap. Inoltre, una volta completato il caricamento della classe,i campi statici e i blocchi statici vengono inizializzati e l'API di registrazione del provider viene utilizzata in questo momento.


public class OracleDriver implements Driver {

    static {
        defaultDriver = null;
        Timestamp timestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
        try {
            if (defaultDriver == null) {
                defaultDriver = new OracleDriver();
                DriverManager.registerDriver(defaultDriver); // Registrazione di OracleDriver
            }
        } catch (RuntimeException runtimeexception) {
        } catch (SQLException sqlexception) {
        }
    }

    ...


In realtà, puoi vedere che OracleDriver utilizza DriverManager.registerDriver() all'interno del blocco statico per registrare OracleDriver, che è un'implementazione di Driver.


Analisi della classe DriverManager

public class DriverManager {

    private DriverManager() {
    }

    private static final Map drivers = new ConcurrentHashMap();
    public static final String DEFAULT_DRIVER_NAME = "default";

    public static void registerDefaultPrivider(Driver d) {
        System.out.println("Driver registrato");
        registerDriver(DEFAULT_DRIVER_NAME, d);
    }

    public static void registerDriver(String name, Driver d) {
        drivers.put(name, d);
    }

    public static Connection getConnection() {
        return getConnection(DEFAULT_DRIVER_NAME);
    }

    public static Connection getConnection(String name) {
        Driver d = drivers.get(name);
        if (d == null) throw new IllegalArgumentException();
        return d.getConnection();
    }


La classe DriverManager è in realtà molto più complessa, ma come descritto sopra, è simile a questa. Come descritto sopra, OracleDriver viene registrato chiamando registerDriver() nel blocco statico di OracleDriver, e l'utente può ottenere un'implementazione di Connection chiamando getConnection().


Guardando più da vicino l'API di accesso dell'utente, getConnection(), puoi vedere che ottiene una Connection dall'interfaccia Driver. Se non esiste un'interfaccia Driver di provider di servizi, è possibile utilizzare la riflessione, come Class.forName(), per restituire l'implementazione di Connection desiderata. In questo caso,l'implementazione di Connection non deve esistere al momento della scrittura del metodo statico di fabbrica.


Invece, utilizziamo l'interfaccia Driver e possiamo facilmente ottenere un'implementazione di Connection corrispondente a quel Driver registrando dinamicamente l'implementazione di Driver.


Per inciso, ho analizzato il codice JDK effettivo del metodo getConnection() di DriverManager, ma puoi saltarlo se non sei molto interessato.


@CallerSensitive
public static Connection getConnection(String url,
    String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();

    if (user != null) {
        info.put("user", user);
    }
    if (password != null) {
        info.put("password", password);
    }

    return (getConnection(url, info, Reflection.getCallerClass()));


Innanzitutto, viene chiamato il metodo statico pubblico getConnection() e url, Properties e CallerClass vengono passati come argomenti al metodo statico privato getConnection(). In questo caso, Reflection.getCallerClass() serve a ottenere la classe che ha chiamato il metodo statico pubblico getConnection(). Se la classe Car chiama getConnection(), è possibile ottenere un oggetto Class tramite Reflection.getCallerClass().


private static Connection getConnection(String url, java.util.Properties info, Class caller) throws SQLException {
    ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
    synchronized(DriverManager.class) {
        if (callerCL == null) {
            callerCL = Thread.currentThread().getContextClassLoader();
        }
    }

    if(url == null) {
        throw new SQLException("L'URL non può essere nullo", "08001");
    }

    SQLException reason = null;
    for(DriverInfo aDriver : registeredDrivers) {
        if(isDriverAllowed(aDriver.driver, callerCL)) {
            try {
                Connection con = aDriver.driver.connect(url, info);
                if (con != null) {
                    return (con);
                }
            } catch (SQLException ex) {
                if (reason == null) {
                    reason = ex;
                }
            }
        }
    }

    if (reason != null)    {
        throw reason;
    }
    throw new SQLException("Nessun driver adatto trovato per "+ url, "08001");


callerCL è un oggetto caricatore di classi e viene creato dal caricatore di classi di caller o dal thread corrente. Successivamente, viene estratto un aDriver dall'elenco di driver registrati nell'applicazione corrente, registeredDrivers. Se questo Driver restituisce true in isDriverAllowed(), viene ottenuta una connessione da questo Driver e restituita. isDriverAllowed() verifica se aDriver esiste in caller.


Vantaggi del framework JDBC

Il punto fondamentale del framework JDBC è che l'interfaccia Driver, l'interfaccia Connection e le classi di implementazione che implementano queste interfacce vengono fornite separatamente. Utilizzando l'interfaccia per creare una cornice, è possibile creare classi di implementazione separate che si adattano a quella cornice, il che è molto flessibile.


Pertanto, anche se viene rilasciato un altro DBMS, il fornitore può fornire Driver e Connection che implementano l'interfaccia, consentendo agli sviluppatori che utilizzano Java di utilizzare la stessa API per i driver di altri DBMS.


Svantaggi dei metodi statici di fabbrica

È necessario un costruttore pubblico o protetto per l'ereditarietà, quindi non è possibile creare sottoclassi se viene fornito solo un metodo statico di fabbrica.


Tuttavia, questo vincolo può essere considerato un vantaggio in quanto incoraggia la composizione piuttosto che l'ereditarietà e deve essere mantenuto per creare tipi immutabili.


I metodi statici di fabbrica sono difficili da trovare per i programmatori.

Poiché non sono esplicitamente evidenziati nell'API come i costruttori, gli sviluppatori devono mitigare il problema scrivendo una buona documentazione API e dando ai metodi nomi che seguono convenzioni ampiamente riconosciute.


Metodi di denominazione dei metodi statici di fabbrica

  • from
    • Accetta un parametro e restituisce un'istanza del tipo corrispondente.
    • Date date = Date.from(instant);
  • of
    • Accetta più parametri e restituisce un'istanza del tipo appropriato.
    • Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
  • valueOf
    • Versione più dettagliata di from e of.
    • BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
  • instance o getInstance
    • Restituisce l'istanza specificata come parametro, ma non garantisce che sia la stessa istanza.
    • StackWalker luke = StackWalker.getInstance(options);
  • create o newInstance
    • Simile a instance o getInstance, ma garantisce che venga creata e restituita una nuova istanza ogni volta.
    • Object newArray = Array.newInstance(classObject, arraylen);
  • getType
    • Simile a getInstance, ma utilizzato quando il metodo di fabbrica è definito in una classe diversa da quella da creare.
    • FileStore fs = Files.getFileStore(path);
  • newType
    • Simile a newInstance, ma utilizzato quando il metodo di fabbrica è definito in una classe diversa da quella da creare.
    • BufferedReader br = Files.newBufferedReader(path);
  • type
    • Versione abbreviata di getType e newType.
    • List<Complaint> litany = Collections.list(legacyLitany);


Riepilogo

I metodi statici di fabbrica e i costruttori pubblici hanno ciascuno il proprio scopo, quindi usali in modo appropriato.


Fonte

제이온
제이온
제이온
제이온
[Effettivi Java] Elemento 5. Non dichiarare risorse, utilizzare l'iniezione di dipendenze Se una classe dipende da risorse esterne, è meglio non utilizzare classi di utilità statiche o singleton. L'iniezione di dipendenze può migliorare la flessibilità, la riusabilità e la facilità di test della classe, e l'utilizzo del pattern di metodo di fa

28 aprile 2024

[Effective Java] Elemento 3. Garantisci il singleton con un costruttore privato o un tipo di enumerazione Presenta tre modi per implementare il modello singleton in Java (membro statico pubblico, metodo di fabbrica statico, tipo di enumerazione) e spiega i pro e i contro di ciascun metodo e le precauzioni da prendere durante la serializzazione. Si consiglia d

27 aprile 2024

[Effective Java] Item 2. Se hai molti parametri nel costruttore, considera di usare un builder Quando si crea un oggetto con molti parametri, l'utilizzo del pattern builder può rendere il codice più pulito e leggibile. Si crea un oggetto builder con i parametri obbligatori, si impostano i parametri facoltativi utilizzando i metodi setter e infine s

27 aprile 2024

[Non specialisti, sopravvivere come sviluppatori] 14. Riepilogo dei contenuti del colloquio tecnico per sviluppatori junior Questa è una guida alla preparazione ai colloqui tecnici per sviluppatori junior. Copre argomenti come la memoria principale, le strutture dati, RDBMS e NoSQL, programmazione procedurale e orientata agli oggetti, override e overload, algoritmi di sostituz
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 aprile 2024

[Javascript] Struttura dell'oggetto (V8) L'oggetto JavaScript in V8 Engine viene ottimizzato come una struttura in base allo stato e convertito in modalità Fast e modalità Dictionary che funziona come una hashmap. La modalità Fast è rapida con chiave e valore in un formato quasi fisso, ma se vie
곽경직
곽경직
곽경직
곽경직
곽경직

18 marzo 2024

Modellazione concettuale dei dati La modellazione concettuale dei dati è il processo di separazione delle entità e di rappresentazione delle relazioni tra le entità tramite un ERD. Un'entità è un'unità di informazioni indipendente, mentre gli attributi sono i dati detenuti dall'entità. Gl
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

8 aprile 2024

AI Full Stack completo con Open Source Nel panorama dell'intelligenza artificiale stanno emergendo sempre più modelli LLM (Large Language Model) open source. Modelli come Mistral, Llama e phi-2, con prestazioni elevate e licenze open source, sono stati rilasciati, e contemporaneamente vengono
RevFactory
RevFactory
RevFactory
RevFactory

5 febbraio 2024

Modellazione logica dei dati La modellazione logica dei dati è il processo di conversione di un modello di dati concettuale in un modello di database relazionale secondo il paradigma del database relazionale, gestendo relazioni 1:1, 1:N, N:M e garantendo l'integrità dei dati attraver
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

9 aprile 2024

Come Rust impedisce i bug di concorrenza Rust è un linguaggio potente che affronta le sfide della programmazione concorrente. Il suo sistema di tipi e il modello di proprietà garantiscono la sicurezza nella condivisione e nel trasferimento di dati tra thread. Tramite pattern di mutabilità intern
곽경직
곽경직
곽경직
곽경직
곽경직

28 marzo 2024